【问题标题】:Do we get a dangling pointer by copying a dangling pointer?我们是否通过复制一个悬空指针来获得一个悬空指针?
【发布时间】:2019-12-17 19:23:16
【问题描述】:

一方面,如果我编写以下代码:

int* fortytwo_pointer () {
  int v = 42;
  return &v;
}

我得到一个悬空指针,我可以通过调用来检查它 printf ("forty two : %d\n", *(fortytwo_pointer()));

另一方面

int* copy (int *pointer) {
  return pointer;
}
int* fortytwo_pointer () {
  int v = 42;
  return copy (&v);
}

不会产生相同的“分段错误”错误。

我希望它也是一个悬空指针的实例,因为值 v 一样超出范围。是真的吗?如果是这样,如何检查指针是否确实悬空?

编辑: This question 更专注于动态检查指针是否有效,例如,如果我们从调用库函数中获取指针。我更感兴趣的是检查代码是否会产生无效指针。

【问题讨论】:

  • 错误仅在您的编译器/调试器中吗?因为在第一种情况下它会注意到,但在第二种情况下,编译器/调试器不知道您正在返回悬空指针。
  • 解除对悬空指针的引用可能“有效”(用引号括起来),但不能保证。这是未定义的行为,您不应依赖它。
  • "可以通过调用 printf 来检查这个"。不,你不能。不能保证会出现故障,实际上在许多情况下可能不会。这就是 C 中所谓的“未定义行为”。不幸的是,该语言没有任何简单的方法可以在访问指针之前检查指针是否有效。有一些特定于平台的方法。但总的来说,C 程序员需要依靠开发最佳实践,如代码审查、测试和调试来根除此类内存问题。还有valgrind等工具可以提供帮助。
  • ...我可以通过调用printf ("forty two : %d\n", *(fortytwo_pointer())); 来检查这一点 不是真的。这是未定义的行为。 另一方面...不会产生相同的“分段错误”错误。因为它是未定义的行为。
  • 这能回答你的问题吗? Testing pointers for validity (C/C++)

标签: c dangling-pointer


【解决方案1】:

是的,你会的。正如您问题的 cmets 中所指出的,您不能使用 printf“检查它”。从弹出函数堆栈的那一刻起,您就在处理未定义的行为。

使用valgrind 运行您的程序,它会指出任何读/写错误。这些可能不会导致您的程序每次都失败,但仍然应该注意。我相信你的悬空指针会出现在那里,valgrind 会很友好地向你展示每个错误发生位置的完整轨迹。

【讨论】:

    【解决方案2】:

    我希望它也是一个悬空指针的实例,因为值 v 超出了范围。是真的吗?如果是这样,如何检查指针是否确实悬空?

    是的,您在int* fortytwo_pointer() 中声明的变量是一个局部变量。这意味着您已声明的变量存储在堆栈帧中,并且在此函数结束时,该变量将被释放,并且没有可取消引用的好地址,这就是为什么 v 是一个悬空指针。

    解决这个问题的建议是使用malloc()calloc() 等函数从堆中分配内存。函数删除堆栈中的所有变量,而不是堆。

    所以,你可以在下面写你的代码:

    int* fortytwo_pointer () {
    int *v = (int*) malloc (sizeof(int));
    if(v == NULL)
    {
        printf("An error occurred.\n");
        getch();
    }
    
    *v = 42;
    return v;
    }
    

    最后,别忘了释放*v 指针。您可以使用 free() 释放它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 2015-08-22
      • 2016-09-19
      相关资源
      最近更新 更多