首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

指针会更改它所指向的地址值

指针会更改它所指向的地址值

基础概念

指针是编程语言中的一个重要概念,特别是在C和C++等语言中。指针是一个变量,其值为另一个变量的地址。通过指针,可以间接访问和修改该地址处的数据。

相关优势

  1. 动态内存管理:指针允许程序员动态分配和释放内存,这在创建复杂数据结构时非常有用。
  2. 提高效率:通过指针传递大型数据结构比复制整个结构更高效。
  3. 实现回调函数和高阶函数:指针可以用来传递函数地址,从而实现回调机制。

类型

  • 指向变量的指针:指向一个具体的变量。
  • 指向数组的指针:指向数组的首元素。
  • 指向函数的指针:指向一个函数。
  • 指向指针的指针:指向另一个指针。

应用场景

  • 数据结构:如链表、树、图等。
  • 函数参数传递:通过指针传递参数,可以实现参数的修改和优化。
  • 动态内存分配:使用mallocfree等函数动态分配和释放内存。

问题与解决

问题:指针会更改它所指向的地址值。

原因

  1. 重新赋值:程序员可以显式地将指针重新赋值为另一个地址。
  2. 动态内存分配:使用malloc等函数分配内存后,指针会指向新分配的内存地址。
  3. 指针运算:通过指针运算,指针可以移动到不同的地址。

解决方法

  1. 确保指针初始化:在使用指针之前,确保其已经正确初始化。
  2. 检查指针的有效性:在使用指针之前,检查其是否为空或指向有效的内存地址。
  3. 避免野指针:确保指针在使用过程中不会指向未知的内存区域。

示例代码

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>

int main() {
    int a = 10;
    int *ptr = &a; // ptr指向a的地址

    printf("Initial address: %p\n", ptr);

    int b = 20;
    ptr = &b; // ptr重新指向b的地址

    printf("Updated address: %p\n", ptr);

    return 0;
}

参考链接

通过上述解释和示例代码,可以更好地理解指针及其地址值的更改机制。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

函数的返回值指向一个指针

定义了一个函数指针类型 callback,它指向一个没有返回值,带有一个整型参数的函数。...函数指针是指一个指向函数的指针变量,它存储了函数的地址,可以用来调用函数。函数指针的定义方式与普通的指针定义方式相似,只是需要在指针类型前面加上函数的返回类型和参数列表。...int (*p)(int, int); 定义了一个名为 p 的指向函数的指针变量,这个函数返回值类型是 int,有两个整型参数。这个函数指针可以指向一个具有相同返回值类型和参数列表的函数。...指针作为参数传递进函数时,实际上传递的是指针所指向的内存地址,函数可以通过指针来访问、修改指针所指向的内存中的数据。 定义了一个名为 swap() 的函数,它有两个参数,都是指向整型变量的指针。...在 main() 函数中,定义了两个整型变量 x 和 y,并输出它们的初始值。然后,将 x 和 y 的地址传递给 swap() 函数,让它交换这两个变量的值。

69420

为什么无返回值的链表的插入操作头结点一定要用指向指针的指针

前言: 为什么链表的插入操作头结点一定要用指向指针的指针?之前自己对这个问题总是一知半解,今天终于花了点时间彻底搞懂了。 总的来说这样做的目的是为了应对“空链表”的情况。...为了防止往一个空链表中插入一个结点时,新插入的结点那就是链表的头指针,这时如果链表的结点是一级指针的话,那么出了链表插入函数的作用域后,头结点又回到了原来的空值。...比如下面的一段程序 1 // 链表的头指针为什么是指向指针的指针.cpp : 定义控制台应用程序的入口点。...这就是因为第20行直接将新节点的值赋值给Phead,导致出了insert函数后,Phead又变成了NULL结点,而没有达到想要的指向新结点的效果。...如果还是不太明白的话,那就先看看“函数是按值传递”的这方面的东西,函数按值传递的时候会拷贝一份实参的副本到形参中,而不是直接把实参赋给形参的。

1.3K70
  • 套接字地址结构的长度之类的值-结果参数要用指针来传递原因

    当一个进程进行系统调用,把参数从用户空间传递到内核时,往往传递的是一个值,即按值传递。...当一个进程进行系统调用,把上次从用户空间传递到内核时的参数,从内核传递到用户空间时,传递的是指向该参数的指针,即按址传递。...这个”值——结果“参数用在套接字地址结构的相关函数中,往往会将一个套接字地址结构的指针和该结构的长度作为函数参数。...当这个函数是将该结构从用户空间传递到内核空间时,传递的长度是一个值,主要的目的是:由于有可能该结构是变长的,比如Unix,Datalink套接字地址结构就是变长的,告诉内核这个结构占用的最大的空间,如果对该结构进行写操作的话...而调用其他的函数对该套接字结构,进行从内核空间到用户空间的传递的话,这个长度参数是一个整型指针了,这个指针指向地址结构中的表示长度的成员。这个长度成员告诉了这个结构最终是用了多少空间。

    1K10

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了...总结: 1.没有虚表指针     1.1没有虚函数的情况下没有虚表指针   2.有虚表指针     2.1虚表指针的产生是看你有没有 virtual这个关键字     2.2虚表指针存储的是虚表的首地址...熟悉了虚表指针, 通过虚表指针找构造,析构,以及虚表指针指向的虚表找虚函数,那么我们看一下普通成员函数调用和虚函数调用有什么区别....认真观察可以看出   1.普通成员函数调用,直接Call    2.虚函数调用     2.1 首先获得虚表指针     2.2 间接调用虚表指针指向的虚表的内容(虚成员函数地址) 总结:   识别调用普通成员函数和虚函数的特征则是...  1.普通成员函数直接调用Call   2.虚函数会通过虚表指针指向的虚表来间接调用.

    1.6K60

    当面试官问你“指针和引用的区别是什么”,TA想听到的是这些

    一、区别基本性质:指针:指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。引用:引用并不是一个真正的变量,它只是另一个已存在变量的别名。...语法:指针:需要使用 * 运算符来访问指针指向的值。引用:可以像普通变量一样使用引用,不需要额外的运算符。使用场景:指针:通常用于动态内存分配、数组、链表等数据结构和函数参数传递。...指针变量的值就是它所指向的变量的内存地址,这个地址可以直接用来访问和操作该变量。指针可以被重新赋值,以指向另一个变量,也可以被赋值为 NULL,表示它不指向任何变量。...三、如何选择通过上面对指针和引用的区别和内存模型的阐述,我们可以归纳总结出以下三点他们在选择时的考虑:必不为空选择引用,可null选择指针:在C++中,引用必须在创建时初始化,并且一旦初始化,就不能更改引用的目标...因此,你应该在解引用一个指针之前,确保它不是空的。可能重新赋值使用指针,否则使用引用:在C++中,指针可以在任何时候改变它所指向的对象。这使得指针在处理动态数据结构(如链表和树)时非常有用。

    7700

    C Primer Plus(六)

    而对于数组来说,必须传递指针。有时传递地址会导致一些问题,例如无意修改了源数据。在 K&R C 的年代,避免类似错误的唯一方法是提高警惕。ANSI C 提供了一种预防手段。...[9] = 44; /* 编译错误 */ 指向 const 的指针不能用于改变值,例如: double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5...}; const double * pd = rates; //使用 const 表明不能使用 pd 来更改它所指向的值 *pd = 29.89; // 不允许 pd[2] = 222.22; /...首先,把 const 数据或非 const 数据的地址初始化为指向 const 的指针或为其赋值是合法的: double rates[5] = {88.99, 100.12, 59.45, 183.11...没问题,更改rates[0]的值 最后,在创建指针时还可以使用 const 两次,使得该指针既不能更改它所指向的地址,也不能修改指向地址上的值: double rates[5] = {88.99, 100.12

    31430

    Java 中是“值传递”还是“引用传递”?

    我选择了一个比较经典的答案,整理给大家! ? 最重要的一点理解是 Dog myDog,它实际上是指向“Dog”的指针。...参数 someDog 设置为值 42,在代码 “AAA” 处,someDog 跟随 Dog,它指向(Dog 地址 42 处的对象),要求Dog(地址为 42 的那个)将他的名字改为 Max。...在代码“BBB” 处,Dog 创建了一个新的。假设它所在地址是 74,我们将参数分配 someDog 给 74。...Java 的工作方式与 C 完全相同。您可以分配指针,将指针传递给方法,按照方法中的指针操作并更改指向的数据。但是,您无法更改指针指向的位置。 Java 总是按值而不是通过引用传递参数。...Java 把引用的地址当做值进行了传递,这么说,你应该就明白了! 上面我的解释,可能会遇到大家!时间关系,我推荐大家去阅读原文吧。

    77220

    const括号前括号后

    const int x = 10; // x 是一个整型常量,其值不能被修改 2. const 在指针类型声明中 const在指针类型声明中的位置决定了它是修饰指针本身还是指针所指向的数据。...const在*之前:表示指针所指向的数据是常量,不能通过这个指针来修改它所指向的数据。...ptr1 指向的常量值 const在*之后(等价于在指针和*之间不加空格):表示指针本身是常量,即指针的值(即它所指向的地址)不能被修改,但可以通过这个指针来修改它所指向的数据(如果该数据不是常量)。...int z = 30; int* const ptr2 = &z; // ptr2 是一个常量指针,指向一个整型变量,不能改变 ptr2 的值(即它指向的地址),但可以修改 z 的值 //ptr2 =...这可以作为一种向调用者承诺的方式,让他们知道他们的数据不会被意外地更改。

    6810

    C:数组与指针,指针与const

    数组与指针 我们都知道一个指针是代表的一个地址,指针,顾名思义,指向一块区域。那么数组呢?数组并不是代表一堆变量,数组其实也是一种指针,指向一个地址,一般是指向数组的首地址,也就是 a[0]的地址。...a==&a[0] a 是一个指针,指向数组 a 的首地址。 下面四种函数原型都是等价的,第一个参数均为一个地址(指针)。...比如定义指针 p 指向数组 a 的第三个单元。 int a[5];int p=&a[2];//如果对指针 p 赋值,则是更改 a[2]的值。...如以下代码: int a=10; int * const p=&a; *p=25;//通过,因为我们改变的是指针所指向地址所对应的值a,a并不是一个常量。 p++;//Error!...编译器无法通过,因为指针p是一个常量(const),它所指向的地址无法被改变。

    81710

    初级程序员面试不靠谱指南(一)

    const *ci_pointer=&i;//指向的东西(地址)可以被修改,值不可以被修改       从上面的代码开始分析,我们分别声明了这两种指针,注释说明了这两种指针的不同,也正如很多书中写的那样...它所占内存里面所包含的应该是它所指向的内容的地址,也就是我们这里格子的编号,也就是E1,E4的pointer格子里面的值是E1(不是0,而就是E1这个值),同理后面两个格子也都是E1这个值。...如下图所示: image.png      从格子E3开始,E3是个const的值,也就是说这里面的这个0是不可以更改的,这很好理解,接下来,我们查看E4格子的值,从声明看,这是一个指针,指向E1格子里面的值...既然const类型是不能改变该内存所存储的值,那么const指针也是不能改变该内存所存储的值,也就是我们不能把E1改成E2,也就是说其指向的地址不能被改变,但是指向的值能不能改变呢?...,只规定了其指向的值是const,虽然它不知道它指向的值是不是const,但是从它来看,它指向的值是不能更改的,也就是你不能通过我来改我指向的值,但是我格子本身的值可以随便改,比如将E1改成E2,这也就是说可以修改其指向

    88790

    借问变量何处存,牧童笑称用指针,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang类型指针(Pointer)的使用EP05

    指针是指什么?指针是存储另一个变量的内存地址的变量。变量是一种使用方便的占位符,用于引用计算机内存地址,一个指针变量可以指向任何一个值的内存地址它指向那个值的内存地址。...,其实就是它所指的变量的基本类型,二者类型是一致的。    ...指针操作     获取一个指针意味着访问指针指向的变量的值。...,将a变量的指针对象传递到方法内,方法内修改的其实是内存地址变量,如此就可以将值类型对象的值对应更改,节省了额外的内存申请空间。    ...假设我们想对方法内的数组进行一些修改,并且对调用者可以看到方法内的数组所做的更改。

    46140

    深入解析C语言数组和指针(0)

    间接访问操作符 通过一个指针访问它所指的地址的过程称为间接访问或解引用指针。操作符为*。根据前面的声明我们有: ?   我们可以知道,d的值为100。...这个值得存储位置我们不清楚,所以它的左值是非法的。 ?   加入了间接操作,右值及为它所指向的地址的值'a',左值为其指向的地址。 ?   ...第三行中,先执行括号中的*f,再执行后面的函数调用(),所以f是一个函数指针,它所指向的函数返回一个整型值。因为函数存放于内存中的某个位置,所以完全可以拥有指向那个位置的指针,即函数指针。   ...第四行结合上个声明很好理解,f还是个函数指针,它所指向的函数返回值是一个整型指针。 ?   ...所以函数一颗自由的操纵它的指针形参,而不必担心会修改对应的作为实参的指针。但是也可以通过形参改变数组对应位置的值,从而更改数组。

    1.3K30

    c++基础之变量和基本类型

    k = 0; //错误,引用必须与变量绑定 指针类型 指针是一个特殊的类型,它本身是一个对象,对象中存储的值是另一个对象的地址。...指针本身应该是一个无符号的整数,指针大小与程序中地址所占内存空间一致,32位程序中指针是4字节,64位程序,指针大小为8字节 使用指针时的限制比引用要宽泛的多 指针可以指向对象,也可以指向另一个指针 指针不需要初始化...,而且后续可以随意更改指向(当然必须指向同一数据类型) 可以多个指针指向同一个对象 指针只能指向对象,指针本身也是一个对象。...所以顶层则是对指针本身进行修饰,底层则是对它所指向的对象的修饰。...指针中的constexpr只对指针本身有效,对它所指向的对象无效 int i = 10; const int *p = &i; //指向整型常量的指针 constexpr int *p = nullptr

    1.6K30

    指针的深入解读笔记

    指针是什么 指针是指向内存单元的编号(地址),可以快速访问地址,加快程序运行速度....,而且在32位平台下是4字节 64位平台下是8字节 而且指针大小与它所指向的东西无关,只于它运行的平台有关 指针类型意义 指针变量的类型虽然与大小无关,但是却决定每次或下次访问时访问的字节大小有关.../决定的是p指向的地址不可更改,但是地址包含的东西可以更改 野指针是指向未知位置的指针,一般是由于没有初始化,越界访问,指向了已经被释放的空间等.我们要规避野指针的存在,可以初始化的时候赋值...= NULL);//如果p不是空指针就报错 如果assert接收的返回值是0就回报错,不是0就继续运行,而且要关闭断言可以使用 #define NDEBUG 数组名指针 首先举个小例子...每次 + 1会跳过一个元素 int *pppp = &arr;//取到了整个数组首元素地址 每次+1会跳过一个数组 我们根据例子也可以倒推如何使用指针去找元素,就和+1 -1和取得是什么类型的指针有关

    10400

    深入探究C语言中的常量指针与野指针概念及其应用

    这种指针的类型是指向常量的指针类型,例如 int * const p;。这意味着你不能通过这个指针来修改它所指向的数据。 2....这意味着你不能修改指针 p 所指向的数据的值。...未初始化的指针:定义指针变量时,如果没有进行初始化,那么该指针的值是随机的,可能指向任意的内存地址。这种情况下,如果尝试通过这个指针去读取或写入数据,可能会导致程序崩溃或其他不可预期的行为。 2....触发段错误:当野指针指向一个不可访问的内存地址时,尝试对其进行解引用操作可能会导致段错误,这是因为程序试图访问一个非法的内存区域。 2....谨慎解引用:在使用指针前,应当确保它指向的是一个有效的内存地址,避免对无效地址进行解引用操作。 4.

    20510

    CC++野指针

    野指针:野指针不同于空指针,空指针是指一个指针的值为null,而野指针的值并不为null,野指针会指向一段实际的内存,只是它指向哪里我们并不知情,或者是它所指向的内存空间已经被释放,所以在实际使用的过程中...避免野指针只能靠我们自己养成良好的编程习惯,下面说说哪些情况下会产生野指针,以及怎样避免。 1....指针变量的值未被初始化:声明一个指针的时候,没有显示的对其进行初始化,那么该指针所指向的地址空间是乱指一气的。...如果指针声明在全局数据区,那么未初始化的指针缺省为空,如果指针声明在栈区,那么该指针会随意指向一个地址空间。...= nullptr) { ……do_somthing } } 2.指针所指向的地址空间已经被free或delete:在堆上malloc或者new出来的地址空间,如果已经free或

    59320

    (迷惑标题大赏)数组就是指针?

    但是可以把它们赋值给指针变量(即自己定义的指针变量),然后再去修改指针变量的值进而达到改变常量。...而指针+1增加的则是一个存储单元,对于数组+1就是下一个元素的地址,而不是按字节来算的。 所以大家在定义数组时一定要声明指向对象的类型,否则指针不知道要存储对象需要多少字节。...简述: 指针的值是它所指向对象的地址。 在指针前面用*可得到该指针所指向对象的值。 指针+1,指针的值增加它所指向类型的大小(以字节为单位哦)。...注意这里不是它们的值,我们知道数组的值可以表示为family[1],那么和family[1]相同的指针表示法则为*(family+1)。...To:间接运算符(*)的优先级高于+。 ? 最后的话:学到指针这一节的童鞋需要多多理解哦,理解之后再刷题会事半功倍。 ?

    25741

    C++指针详解

    指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。...以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。...*p的运算结果就五花八门了。总之*p的结果是p所指向的东西,这个东西有这些特点:它的类型是p指向的类型,它所占用的地址是p所指向的地址。...*p=24;//*p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,*p就是变量a。 ptr=&p;//&p的结果是个指针,该指针的类型是p的类型加个*,在这里是int**。...*str也是一个指针,它的类型是char*,它所指向的类型是char,它指向的地址是字符串"Hello,this is a sample!"的第一个字符的地址,即'H'的地址。

    50520

    第七节(指针)

    那么,指针如何储存多字节变量的地址? 实际上,变量的地址是它所占用字节的首地址(最低位的地址)。.../*其他代码已略去*/ 指针中储存的是它所指向变量的第1个字节地址。...函数使用的是真正的数组元素,因此可以在函数中修改储存在该数组中的值。 八:小结 本次介绍了C语言的重点内容一一指针。 指针是储存其他变量地址的变量。指针“指向”它所储存的地址上的变量。...5:确定变量的地址要使用什么运算符? 取址运算符是& 6:通过指针确定它所指向位置上的值,要使用什么运算符? 要使用间接运算符*。在指针名前写上*,引用的是该指针所指向的变量。 7:什么是指针?...直接访问:cost = 100; 间接访问:*p_cost = 100; 4.根据练习题3,打印指针的值和它所指向的值。

    20140

    指针

    _ *p = 20,此处的 * 是解引用操作符。 &为取地址操作符 指针的类型是根据原来值的类型来确定用什么类型的指针。如:char类型,那就用char* 。...去掉指针变量名剩下的就是指针的类型 关于指针类型的声明有人可能会问用不同的类型声明可以吗?当然可以,但是会出现一些问题。...,它所指向的空间被返还给操作系统 再次对它解引用进行访问就造成非法访问。...要改变i的值p1要解引用2次才可以改变 2. 字符指针 能够指向字符数据的指针 形如这样的char* p 这里就讲比较难的地方吧!...但是p1,p2可不能储存"abcef"这样的常量字符串,它们只是储存了首字符的地址,所以p1和p2相等.并且p1,p2所指向内存的数据不能更改,因为初始化的常量字符串是不能更改的,可以这样写 c const

    30360
    领券