我正在考虑指针初始化,并尝试了以下两种情况:
#include <stdio.h>
int main(int argc, char **argv)
{
int *d;
int f;
int p;
*d = 6;
printf("%d %d %dn", *d, f, p);
return 0;
}
这段代码在以下行出现分段错误(见gdb):
*d = 6;
这是有意义的,因为我试图在一个随机地址存储一个值。
然后我尝试了以下操作:
#include <stdio.h>
int main(int argc, char **argv)
{
int *d;
int f = 10;
int p = 9;
*d = 6;
printf("%d %d %dn", *d, f, p);
return 0;
}
运行到输出完成:
6 10 9
如果只有f
初始化为10 (p
未初始化为10),反之亦然,程序仍然以输出
6 10 0
或
6 0 9
(p
initialized)。我不明白为什么会这样。我最初的猜测是,f
或p
的初始化为d
的安全初始化提供了空间或定向内存。我也考虑过堆栈分配,但仍然不确定。
你的第一个问题是在*d = 6;
,因为你试图解引用一个无效的指针。
d
没有初始化(分配内存),它指向一个无效的内存位置。任何将导致未定义行为的解引用尝试。
哎呀,第二段代码也出于同样的原因产生了UB。
另外,在第一个代码片段中,通过写入
printf("%d %d %dn", *d, f, p);
其中f
和p
是未初始化的自动局部变量,您试图读取不确定的值,这再次产生UB。在第二个代码片段中,通过显式初始化可以避免这种情况。
在你的程序中-
*d = 6; // writing to an invalid memory location
指针未初始化。因此,当您解引用它(*d)时,您将访问内存中未经授权的位置,从而导致分段错误。
你也尝试打印未初始化的局部变量-
printf("%d %d %dn", *d, f, p); // where f and p are indeterminate
因此,你的代码调用未定义行为,你的程序给出的输出可以是任何东西。 这段代码在以下行出现分段错误(见gdb):
*d = 6;
这是有意义的,因为我试图给a随机地址价值。
这段错误是有道理的,但你的解释是非常不正确的。您不以任何方式给予/或分配一个地址给一个值。相反,您正在尝试将值存储在未指定的地址。
理解d
和*d
之间的区别是至关重要的。前者(正如您所声明的那样)是一个指针,预计将保存int
的地址。后者是d
指向的int
。如果d
实际上没有被初始化为指向int
,那么计算表达式*d
将产生未定义的行为。
未定义的行为就是——未定义。你不能期望类似的未定义行为在其他情况下产生相同的实际行为,你甚至不能依靠这种行为来表现出明显的破碎迹象。任何事情都有可能发生,原则上包括程序员希望发生的事情。
声明指针变量不会自动导致分配任何存储空间。有许多方法可以初始化d
,但其中一种方法是
d = &f;
您需要使用malloc()分配内存
这部作品:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int *d;
int f = 10;
int p = 9;
d = /*(int *)*/malloc(sizeof(int) * 1);
if (!d)
exit(-1);
*d = 6;
printf("%d %d %dn", *d, f, p);
free(d);
return 0;
}