C中未初始化指针的值

时间:2019-03-21 13:28:56

标签: c pointers initialization

假设我们在C中具有以下声明:

double d[25], * p;
int * t;
char * c;

我们如何解释以下printf()结果?

printf("d : %x\t",d);
printf("p : %x\t",p);
printf("t : %x\t",t);
printf("c : %x\t",c);

其中将打印ligne:

d : 62fd30    p : 1    t : 0    c : 39    

我们可以很清楚地看到d的内存地址,但是p,t和c看起来都不像地址。我曾经认为,未初始化的指针在声明后采用Null值。我错了吗?我们如何解释这些结果?

3 个答案:

答案 0 :(得分:5)

默认情况下,

所有自动(非静态局部)变量将使用 indeterminate 值(可能看起来是随机的或垃圾的)未初始化。变量是否是指针都没有关系。

此外,仅读取未初始化指针的值并不会自动UB(在C中),但是取消引用绝对会是未初始化指针。

但是,正如一个评论中所述,您需要使用"%p"来打印指针(从技术上讲,它们也必须转换为void *)。 printf格式说明符和参数类型 do 不匹配会导致UB。

答案 1 :(得分:3)

您不能假定声明后任何指针都将被零初始化-C标准此时不暗示任何内容。其他类型的值也是如此。这就是为什么在声明时设置变量值的一种好习惯,例如:

int * t = NULL;

某些编译器会对变量进行零初始化,但这是特定于工具的功能。

答案 2 :(得分:3)

  

我以前认为未初始化的指针使用   声明后的值。我错了吗?

,您的假设不正确。用自动存储声明的未初始化指针始终包含垃圾数据或垃圾数据,即不是有效地址,因此最好在声明时首先使用NULL进行初始化。对于例如

double *d = NULL;
/* some processing */
if(d == NULL) {
  /* @TODO error handling. Not allowed to de-reference NULL pointer */
}

这里

double d[25];
printf("d : %x\t",d);

d25的double数组和数组名称本身的地址的数组,而使用d打印%x会导致不确定的行为,即使您的编译器也可能已经警告过您

  

main.c:5:19:警告:格式指定了类型'unsigned int',但是   参数的类型为'double *'[-Wformat]

但是您似乎忽略了编译器警告,一个不应该。始终使用最少的标志,例如-Wall来编译代码。例如

gcc -Wall -Werror -Wpedantic test.c

要打印阵列名称,请使用%p格式说明符。例如

double d[25];
printf("Array d : %p\t",(void*)d);

int指针tchar指针c相似,使用%p格式说明符代替%x。另外,请勿在代码中保留任何未初始化的指针。

int * t; /* initialized with valid address else 
            dereferencing uninitialized pointer causes UB */
printf("t : %p\n",(void*)t);