【问题标题】:Dangling reference. Alternatives for dangling pointers and references?悬空参考。悬空指针和引用的替代方案?
【发布时间】:2010-11-24 19:49:27
【问题描述】:

以下代码产生悬空引用:

int main()
{
  int *myArray = new int[2]{ 100, 200 };
  int &ref = myArray[0];
  delete[] myArray;
  cout << ref;  // Use of dangling reference.
}

我知道我不应该删除数组,但在大型程序中,如果有人删除了我引用的内存怎么办?能保证没有人删除数组吗?

对抗悬空引用和悬空指针的最佳策略是什么?

【问题讨论】:

  • stackoverflow.com/questions/395123/raii-and-smart-pointers-in-c。或者在这个例子中,最好的选择是不这样做。
  • 动态分配数组的最佳替代方案是std::vector。在 C++ 中几乎不需要使用new[]delete[]。 - 但即便如此,迭代器和引用确实很容易失效。一般来说,你不应该长期引用那些可能不会有很长生命周期的东西。
  • 谢谢本斯。 “不应该长期引用那些可能不会有很长寿命的东西。”我会听从这个建议

标签: c++ pointers reference


【解决方案1】:

在你完成之前不要删除内存。

听起来很愚蠢,但这是您唯一的保护措施 - 正确了解谁拥有每个变量背后的内存,以及何时可以安全地释放它。

智能指针可以提供帮助,但上述内容仍然适用。

有些静态分析工具可能会识别出您在这里遇到的琐碎案例,但即便如此,这也应该是第二道防线,您的第一道防线是内存管理方面的纪律。

【讨论】:

  • 我知道我不应该删除内存,但这在大型程序中无法控制。我不能要求所有开发人员不要删除 arrayXYZ。但我认为智能指针是我一直在寻找的。谢谢史蒂夫
  • 但问题是我不能拥有智能指针的集合或数组,可以吗?
  • 你确定我可以在数组中使用智能指针吗?我想我读过关于 auto_ptr 它不能与数组一起使用,智能指针的情况是否相同?
  • @blueskin,诸如 shared_ptr 之类的智能指针在数组中使用是安全的。它唯一的 auto_ptr 具有奇怪的语义导致问题。
  • @blueskin:我很确定即使使用智能指针,没有纪律的程序员仍然会搞砸(例如,通过存储指向所持有对象的普通指针)。即使使用智能指针,您也必须遵循最佳实践。 - 不过,把事情做好会更简单。
【解决方案2】:

保持它们的正确范围:

int main(){
  int *myArray;
  myArray = new int[2]{ 100, 200 };
  {
    int& ref = myArray[0];
    // use the ref here
    cout<<ref;  \\no longer a dangling reference
  } // ref falls out of scope here
  delete[] myArray;
 }

【讨论】:

    【解决方案3】:

    病人:医生,我这样做的时候很痛 这……

    医生:那就别这样了……

    在引用内存时不要释放内存。


    编辑

    唯一的方法是调试,进行良好的单元测试并在 valgrind 下运行,或者在 valgrind 下运行您的程序。

    【讨论】:

    • 我在问题中添加了更多内容。我的问题并不能完全代表我想问的问题。谢谢
    • @blueskin 答案(和所有其他人)仍然有效。 “不要那样做”,并且没有办法检查您的引用是否无效(或指针指向无效的内存位置)
    • 是的。我明白了。可悲的是,那是真的.. 如果我在面试中被问到这个并要求解决方案怎么办。我不能说“不要那样做”:D..
    【解决方案4】:

    这里的所有答案都是“小心!”和“使用良好的编程习惯!”。
    这不是一个非常令人满意的答案。这些问题在 C 中已经存在了 40 多年,并且在任何大型 C++ 项目中仍然很常见。

    您会听到人们推荐的最重要的指导方针是:

    • 使用智能指针
    • 使用 RAII

    两者都是正确的,但你可以做的更多。

    2015 年,标准 C++ 基金会发布了Guidelines Support Library

    您可以编写静态类型安全且没有 资源泄露。您可以在不损失性能的情况下做到这一点,并且 不限制 C++ 的表达能力。该模型用于类型和 资源安全的 C++ 已使用 ISO 的组合实现 标准 C++ 语言工具、静态分析和微小的支持 库(用 ISO 标准 C++ 编写)。

    我建议您将 GSL 的 Owner&lt;&gt; 与静态分析工具一起使用。
    这将保证安全的行为。

    【讨论】:

      【解决方案5】:

      良好的编程习惯。编译器为您提供了足够的绳索来吊死自己;你有责任确保你不这样做。

      换句话说,如果你不引用一个数组,然后删除它,那么你就不会有问题。

      “但是,万一发生了呢?”

      真的,没有简单的答案。这一切都与培训有关,并且知道如何使用您尝试使用的工具。

      【讨论】:

      • “足够用来吊死自己的绳子”.. LOL.. 那是真的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2011-07-14
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      相关资源
      最近更新 更多