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

Ale*_*oks 2 c gcc

我有以下代码:

#include <stdio.h>

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);
}
Run Code Online (Sandbox Code Playgroud)

输出最终d.arg1是不是NULL而且d.arg2是0.例如:

arg1: 0x7fff84b3d660 | arg2: 0
Run Code Online (Sandbox Code Playgroud)

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

#include <stdio.h>

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);
}
Run Code Online (Sandbox Code Playgroud)

输出总是导致:

arg1: (nil) | arg2: 4195264 | test: (nil)
Run Code Online (Sandbox Code Playgroud)

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

hac*_*cks 5

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

C11 6.7.9初始化:

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

引用这个答案:

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