![](/img/trans.png)
[英]Why is de-referencing the pointer and printing the value crashing the program
[英]Why does a pointer gives a garbage/random value on initializing and de-referencing after declaration?
代码片段-1
int x=3;
int *p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);
代码片段-2
int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);
Snippet-1 给出 output x=3 & p=3,但 snippet-2 给出 x=3 & p=一些随机值
请解释
这一行:
int *p=&x;
是带有初始化的p
声明。 它将p
(一个int *
)初始化为&x
。
相比之下,这一行:
*p=&x;
是一个任务。 它首先取消引用p
,然后将&x
分配给取消引用的 object。 这是错误的,原因有二:
p
没有指向任何地方,因此尝试取消引用它会调用undefined behavior 。p
确实指向某个地方,您也会尝试将int *
分配给int
。此代码段具有未定义的行为
int x;
int *p;
x=3;
*p=&x;
printf("x= %d\n",x);
printf("p= %d\n",*p);
因为指针p
未初始化并且具有不指向有效 object 的不确定值。 所以这个说法
*p=&x;
通过取消引用指针 ( *p
) 试图访问无效地址的 memory。
似乎相反,这种说法
*p=&x;
你的意思是
p = &x;
即指针获取变量x
的地址。
注意printf这种调用的输出信息
printf("p= %d\n",*p);
令人困惑。 最好写
printf("*p= %d\n",*p);
即输出的不是指针本身的值,而是输出的指向的object的值。
您应该区分声明和表达式中星号的含义。
在这样的声明中
int *p=&x;
星号表示这里声明了一个指针,它获取变量 x 的地址。
在这样的表达式语句中
*p=&x;
星号表示解引用运算符,用于通过存储在用作地址的指针中的值访问指向的 object。
int *p=&x;
相当于
int *p;
p = &x; // <== p, not *p
p = &x
获取变量 x 的地址,并将其放在p
(它是一个指针)中。
这与您在片段 2 中所做的不同
*p = &x; // Not the same
*p = &x
获取变量 x 的地址,并将其放在p
指向的位置。 因此, p
仍然指向同一个位置,但该位置写入了不同的值。 (并且因为p
没有初始化,它没有指向任何有用的东西,导致未定义的行为)
int *p = &x;
(在第一个片段内)
不同于
int *p;
*p = &x;
(在第二个片段内)
在第一种情况下,您通过x
的地址初始化p
。
在第二种情况下,当在第二个语句中使用*p
时,您取消引用指向无效 object 的p
并尝试将x
的地址分配给不存在的 object p
应指向的地址,这会调用未定义的行为。
通常这应该在编译时至少给你一个警告。 如果未显示,请引发编译器警告。
声明中的*
用于指示指针。
声明后的*
用于取消引用指针。
如果您希望代码段 2 正常运行,则需要在分配时省略*
:
int x;
int *p;
x = 3;
p = &x; // No * operator here.
printf("x = %d\n", x);
printf("*p = %d\n", *p);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.