Valgrind 将指针与 NULL 进行比较
Posted
技术标签:
【中文标题】Valgrind 将指针与 NULL 进行比较【英文标题】:Valgrind Comparing pointer with NULL 【发布时间】:2018-06-26 12:12:34 【问题描述】:我正在使用 Valgrind 调试我的代码,当我通过将 struct
与 NULL
进行比较来测试 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 进行比较的主要内容,如果未能解决你的问题,请参考以下文章