我在考虑指针初始化并尝试了以下两种情况:
#include <stdio.h>
int main(int argc, char **argv)
{
int *d;
int f;
int p;
*d = 6;
printf("%d %d %d\n", *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 %d\n", *d, f, p);
return 0;
}
这将通过输出完成:
6 10 9
如果只将f
初始化为10(p
未初始化),反之亦然,程序仍然以输出
6 10 0
或
6 0 9
(p
已初始化)。我不明白为什么会这样。我最初的猜测是,f
或p
的初始化会产生空间或内存,以允许d
的安全初始化。我也考虑过堆栈分配,但我仍然不确定。
答案 0 :(得分:2)
您的第一个问题出在*d = 6;
,因为您正试图取消引用无效指针。
d
未初始化(已分配的内存),并且它指向无效的内存位置。任何取消引用的尝试都会导致undefined behavior。
FWIW,第二个代码也出于同样的原因产生UB。
此外,在第一个代码段中,通过编写
printf("%d %d %d\n", *d, f, p);
其中f
和p
是未初始化的自动局部变量,您尝试读取不确定的值,这又会产生UB。通过显式初始化在第二个片段中避免这种情况。
答案 1 :(得分:1)
在您的计划中 -
printf("%d %d %d\n", *d, f, p); // where f and p are indeterminate
您将指针保留为未初始化的值。因此,当您取消引用它(* d)时,您将访问内存中未经授权的位置,从而导致分段错误。
您还尝试打印未初始化的局部变量 -
{{1}}
因此,您的代码会调用 未定义的行为 ,并且您的程序会提供输出,字面上可以是任何内容。
答案 2 :(得分:1)
您需要使用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 %d\n", *d, f, p);
free(d);
return 0;
}
答案 3 :(得分:1)
此代码段错误(在gdb中看到):
*d = 6;
这是有道理的,因为我试图给一个随机地址 值。
段错误确实有意义,但你的解释是非常不正确的。您不以任何方式为值赋予/或分配地址。相反,您试图将值存储在未指定的地址。
理解d
和*d
之间的区别至关重要。前者(如您所声明的那样)是一个指针,预计会保存int
的地址。后者是int
所指向的d
。实际上,如果d
尚未初始化为int
,那么评估表达式*d
会产生未定义的行为。
未定义的行为就是 - undefined。您不能指望类似的未定义行为来源在其他情况下产生相同的实际行为,并且您甚至不能依赖该行为来显示明显的破坏迹象。任何事情都可能发生,原则上包括程序员想要发生的事情。
声明指针变量不会自动导致分配任何存储。您可以通过多种方式初始化d
,但有一种方法可以
d = &f;