Valgrind 将指针与 NULL 进行比较

Posted

技术标签:

【中文标题】Valgrind 将指针与 NULL 进行比较【英文标题】:Valgrind Comparing pointer with NULL 【发布时间】:2018-06-26 12:12:34 【问题描述】:

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

void main()

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

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

【问题讨论】:

将它与 NULL 进行比较的重点是确定它是否已初始化。 咦?!?!这完全没有意义。如果它没有被初始化,将它与 anything 进行比较是没有用的。 这是未定义的行为,因为指针没有获取指针本身的地址。见(Why) is using an uninitialized variable undefined behavior?。 【参考方案1】:

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

int *pointer = NULL;

一般情况下,您无法检测变量是否已分配,没有神奇的“无值”值,变量的所有位都用于包含实际值。

【讨论】:

不清楚“变量的所有位都用于包含实际值”,因为我不认为指针被指定为不包含填充。 IAC,最后一句看起来没必要。【参考方案2】:

unassignedPointer 是一个未初始化的局部变量,读取此类变量将导致未定义的行为,即您永远不知道会发生什么。在大多数架构上,这些变量将只包含内存垃圾,您的代码将不打印任何内容或“此指针为 NULL”,具体取决于您的运气。您应该正确初始化变量:

void main()

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

【讨论】:

【参考方案3】:

先到这里

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

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

‘unassignedPointer’在此函数中未初始化使用 [-Werror=未初始化]

如果您使用正确的警告标志(如 -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

程序启动:定义返回类型为int,不带参数:

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

或带有两个操作参数(此处称为 argc 和 argv ,尽管 可以使用 yn ames,因为 ya 是函数的局部变量,其中 你重新声明):

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

这个

void main()  
   /*some code */

不正确,改用

int main(void) 
    /*some code */

【讨论】:

"unassignedPointer ... & 取消引用它会导致未定义的行为" 是真的,但 OP 的代码不会取消引用 unassignedPointer 是的,@chux 我只是在暗示如果 OP 试图取消引用未初始化的指针,这会导致 UB,尽管 OP 没有在代码中这样做。 是的,同意 @chux 取消引用 int *unassignedPointer;int *unassignedPointer = NULL 导致 UB。【参考方案4】:

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

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

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

【讨论】:

以上是关于Valgrind 将指针与 NULL 进行比较的主要内容,如果未能解决你的问题,请参考以下文章

c++ 将指针推入指针优先级队列会导致立即 valgrind 错误

SQL查询结果中的NULL代表啥意思

Valgrind 显示分配的内存比实际更多

Valgrind进行内存泄漏检测

Valgrind:可能丢失可以被视为绝对丢失吗?

Boost python,将原始指针与托管指针进行比较?