【问题标题】:What makes a heap allocated object "referenced" in C++?是什么让 C++ 中的堆分配对象“被引用”?
【发布时间】:2020-11-11 02:20:36
【问题描述】:

在 C++ 中,什么决定了要引用的堆分配对象? Mark Allen Weiss 在他的《Data Structures and Algorithm Analysis in C++》一书中写道“当一个对象被 new 分配的不再引用时,必须对对象应用删除操作(通过指针)”我觉得这句话有点令人困惑的是,我所理解的是指针持有对内存地址的引用,但是代表这个地址的对象是如何被其他东西引用的呢?当其他东西不再引用它时,我必须调用删除?

【问题讨论】:

  • int *a = new int{1}; int *b = a; ab 都引用了new int{1}分配的内存
  • @AbdelRahmanMahmoud 在那个例子中,只有一个堆分配的对象,所以只有一个要删除的对象。
  • 这没关系,但在许多情况下是不必要的。同样,删除后a 仍将指向您删除的内存,但是在释放内存后,您不能再次取消引用指针。
  • @AbdelRahmanMahmoud 这完全不正确。没有关于“引用”和delete 的规则。规则是你应该在deletenew分配的对象当你不再需要它们时
  • @AbdelRahmanMahmoud 成为坏习惯的原因有很多。一个是如果你有两个指向同一个对象的指针,你不能总是将两者都设置为nullptr,所以你不能确保指针是有效的或者nullptr无论如何,所以没有任何好处。另一个是它可以隐藏代码所依赖的信息,例如指针先前指向有效对象的事实。您不能仅仅假设插入b = nullptr 是安全的;在某些代码中的 free (b); 之后。

标签: c++ memory heap-memory allocation


【解决方案1】:

这本书不正确。没有关于“引用”和delete 的规则。规则是,当您不再需要 deletenew 分配的对象时,您应该使用它们。

当书上说该对象“不再被引用”时,它实际上意味着不再需要该对象。你必须至少有一个对该对象的引用,否则你甚至不能delete它!

“引用”意味着您的程序知道对象的地址,因为它存储在变量中。

【讨论】:

    【解决方案2】:

    代表这个地址的对象是如何被某物引用的 还有吗?

    这意味着您的程序中的其他东西正在持有指向堆分配对象的内存位置的指针(或引用,就我们的目的而言,这相当于同一件事)。

    当其他东西不再引用它时,我必须 调用删除?

    好吧,您不必 这样做——另一种方法是忘记对象并且根本不删除它,这就是所谓的内存泄漏。唯一的问题是,如果您不删除该对象,则该对象占用的 RAM(和任何其他资源)将永远不会被释放(至少在您的程序退出之前不会),如果您不断泄漏对象,最终,您的计算机将耗尽 RAM 并停止运行。所以对于生命周期很短的程序来说,马虎不得,不要删除不再引用的对象,但一般情况下还是自己清理比较好。

    此外,您能否告诉我有关我可以阅读的资源 澄清 C++ 中内存的使用?

    任何像样的 C++ 书籍都应该有一个章节;一般来说,最好的做法是在使用堆分配对象时使用智能指针(如std::unique_ptrstd::shared_ptr)而不是普通的旧C 样式指针。这种方式更不容易出错,因为您永远不必弄清楚何时是调用delete 的正确时间,因为指针类会在正确的时间自动为您调用 delete。

    【讨论】:

      【解决方案3】:

      只是为了说明类似的东西

      int* a = new int;
      int* b = a;
      

      看起来像这样:

      +--- |一个 | --\ +---+ \ +-----------------------+ >--> |堆分配内存 | +---+ / +-----------------------+ |乙 | --/ +---+

      ab 两个指针都指向完全相同的内存。

      如果您在此之后delete a,则ab 均无效。

      【讨论】:

        【解决方案4】:

        我不会对那里语言的精确选择过于着迷。他想说的是,如果您在堆上分配一个对象,那么您有责任在完成后取消分配它。否则,它将保持有效并浪费内存。

        您可以完全处理一个对象,即使它仍然被引用。确切地说,何时删除对对象的所有引用以及何时取消分配取决于您。关键是您绝对不想在取消分配后尝试使用它,并且您也不希望在很长一段时间内无法取消分配大量对象并浪费内存。

        幸运的是,在现代 C++ 中,您可以使用许多工具来简化此操作,包括移动语义、unique_ptr 等等。

        【讨论】:

          猜你喜欢
          • 2017-07-03
          • 2020-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-29
          • 2017-06-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多