【问题标题】:Valgrind Comparing pointer with NULLValgrind 将指针与 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?

标签: c valgrind


【解决方案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 中的警告应该永远被忽略。该语言假定您知道自己在做什么,并且没有其他语言所具有的任何保护措施。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2022-11-03
      • 2013-05-04
      • 2013-07-05
      相关资源
      最近更新 更多