打印指针时出现奇怪的行为

我有以下代码:

#include  typedef struct { int* arg1; int arg2; } data; int main(int argc, char** argv) { data d; printf("arg1: %p | arg2: %d\n", d.arg1, d.arg2); } 

输出最终是d.arg1不是NULLd.arg2是0.例如:

 arg1: 0x7fff84b3d660 | arg2: 0 

当我添加一个指向main的指针时,没有任何变化。 但是,当我打印指针时:

 #include  typedef struct { int* arg1; int arg2; } data; int main(int argc, char** argv) { data d; int* test; printf("arg1: %p | arg2: %d | test: %p\n", d.arg1, d.arg2, test); } 

输出总是导致:

 arg1: (nil) | arg2: 4195264 | test: (nil) 

为什么我会遇到这种行为? 我不明白如何打印另一个指针值会将不同指针的值更改为NULL。 请注意,我使用的编译器是GCC 4.8.2。

您遇到此行为,因为您的程序调用未定义的行为d在您的程序中未初始化,因此其值是不确定的 ,这会调用未定义的行为。

C11 6.7.9初始化:

如果未显式初始化具有自动存储持续时间的对象,则其值不确定。

引用这个答案 :

不确定的值比未指定的更加未指定。 它可以是未指定的值或陷阱表示。 陷阱表示是标准 – 代表一些神奇的价值,如果你试图将它分配给任何东西,会导致不确定的行为。 这不一定是实际价值; 可能最好的思考方式是“如果C有exception,陷阱表示将是一个例外”。 例如,如果您声明int i; 在一个块中,没有初始化,变量i的初始值是不确定的,这意味着如果在初始化之前尝试将其分配给其他东西,则行为是未定义的,并且编译器有权尝试所述恶魔鼻子戏法。 当然,在大多数情况下,编译器会做一些不那么戏剧性/有趣的事情,比如将其初始化为0或其他一些随机有效值,但无论它做什么,你都无权反对。

您应该初始化d以获得确定性结果:

 data d = {0, 42}; 

要么:

 data d; d.arg1 = 0; d.arg2 = 42; 

如果没有初始化,使用值会导致未定义的行为

您正在访问未初始化的值。 这会导致未定义的行为(意味着任何事情都可能发生,包括程序崩溃)。

要修复,请在使用前初始化值,例如:

  data d = { 0 }; 

d未初始化,因此它可以包含任何内容。