Valgrind 比较指针与 NULL

Valgrind Comparing pointer with NULL

我正在使用 Valgrind 调试我的代码,当我通过将 structNULL 进行比较来测试它是否已初始化时,我收到了警告。

void main()
{
    int *unassignedPointer;
    if(unassignedPointer == NULL)
        printf("This Pointer is NULL\n");
}

此代码可以编译并运行,但是当 运行 通过 Valgrind 时,它会发出警告:条件跳转或移动取决于未初始化的值。将它与 NULL 进行比较的全部意义在于确定它是否已初始化。这是一种危险的做法,还是我应该忽略这些警告?

你当然不应该忽略这个警告,你应该通过初始化指针来修复它:

int *pointer = NULL;

一般来说,您无法检测到变量是否已被赋值,没有神奇的 "no value" 值,变量的所有位都用于包含实际值。

unassignedPointer 是一个单元化的局部变量,读取这样的变量会导致未定义的行为,即你永远不知道会发生什么。在大多数架构中,这些变量将只包含内存垃圾,您的代码将不打印任何内容或 "This pointer is NULL" 取决于您的运气。您应该正确初始化变量:

void main()
{
  int *unassignedPointer = NULL;
  if(unassignedPointer == NULL)
  printf("This Pointer is NULL\n");
}

首先在这里

int *unassignedPointer; /*here it can points to any unknown memory location */ 

unassignedPointer 未初始化且未指向有效的内存位置和取消引用(如果您尝试过)会导致未定义的行为。你的编译器可能会警告你

‘unassignedPointer’ is used uninitialized in this function [-Werror=uninitialized]

如果您使用 -Wall 等适当的警告标志编译代码,那么首先使用 NULL 初始化 unassignedPointer,例如

int *unassignedPointer = NULL;

这是一种危险的做法,还是我应该忽略这些警告?永远不要忽略编译器警告。使用

更好地编译任何简单代码
gcc -Wall -Wstrict-prototypes -Werror test.c   /* Werror, stops the compilation, convert warning into error */ 

另请阅读 C 语言标准草案 n1256 部分 5.1.2.2.1

Program startup: It shall be defined with a return type of int and with no parameters:

int main(void) { /*
...
*/ }

or with tw op arameters (referred to here as argc and argv ,though an yn ames may be used, as the ya re local to the function in which the ya re declared):

int main(int argc, char *argv[]) { /*
...
*/ }

这个

void main() { 
   /*some code */
}

不正确,请改用

int main(void) {
    /*some code */
}

当一个变量未初始化时,这意味着它没有被明确地赋予初始值。这意味着它可以有 任何 值,包括 NULL 或其他一些值。

形式上,没有静态存储持续时间的未初始化变量(即未标记 static 的局部变量)具有 不确定 值。

此外,作为一般规则,C 中的警告应该永远不会 被忽略。该语言假定您知道自己在做什么,并且没有其他语言所具有的任何保护措施。