【问题标题】:What do I have to garbage collect in a C++ destructor我必须在 C++ 析构函数中收集什么垃圾
【发布时间】:2012-01-31 04:43:05
【问题描述】:

我正在编写一个 C++ 析构函数(我希望这是正确的术语;我是 C++ 新手),我对垃圾收集到底需要什么并不肯定。假设我有 2 个指针作为实例变量,我需要对它们进行垃圾收集吗?如果我有一个对象作为实例变量呢?还是指向对象的指针?

我只是对需要删除的内容和自动清理的内容有点模糊。

谢谢

【问题讨论】:

  • 迂腐提示:您不会在 C++ 中“收集垃圾”。你删除他们。
  • C++ 没有垃圾收集器。你是想写一个,还是只是想在析构函数中删除一个对象?为什么不使用智能指针?
  • 如果你来自其他语言,C++ 析构函数概念的意思是,你弄脏了什么,你应该自己清理它。你不能对此大意。

标签: c++ memory-management destructor smart-pointers raii


【解决方案1】:

一般的经验法则是...如果您致电new,请致电delete。如果您致电new[],请致电delete[]。如果您在类之外访问这些指针并有效地共享它们,您将需要小心“拥有”对象deleteing 共享对象,而它们仍在使用中。垃圾收集不是一个正确的术语。你想destroy 对象和free 它的内存。这就是delete/delete[] 所做的。 new/new[]分配内存和construct一个对象。

在 C++ 中,没有垃圾收集器。您必须“手动”处理它。这并不是说这一切都很乏味。您可能会开始使用 智能指针 来为您处理其中的一些逻辑。请参阅this question 了解更多信息。

【讨论】:

  • 唯一提到所有权的答案。 +1!
  • 因此,如果我有一个指向对象的指针作为实例字段,并且假设没有其他人知道它,那么我将不得不删除该对象而不是指针...是吗对吗?
  • 语法类似于delete Address。指针实际上是一些数据,将地址存储在对象的内存中。所以,如果你有int* Number;,你应该使用delete Number;删除Number指向的东西。您不是在删除指针本身,而是在删除指针指向的内容。语法只需要一个地址,指针存储地址。
【解决方案2】:

您必须使用new 分配的每个指针delete。就这么简单,也这么复杂;在deleted 之前,您不能丢失new 分配的任何指针。

另外,您需要确保如果您使用new[] 分配一个指针,您调用delete[] 来释放它。

这与您在类实例中碰巧拥有的指针无关。您需要知道谁拥有它们(所有者是负责删除它们的人)。如果您的对象拥有这些指针,那么它应该删除它们。如果它不拥有它们,那么它不应该拥有它们。

这也是有经验的 C++ 程序员尽可能避免使用裸指针的原因。智能指针允许您在语言中语义地表达所有权类型。这样,您就不必跟踪谁拥有什么;您可以通过所使用的智能指针的类型知道谁拥有它。

【讨论】:

  • 你可能想提一下newnew[]deletedelete[]之间的区别
【解决方案3】:

您必须在使用new 创建的每个空间上调用delete,在使用new[] 创建的每个区域上调用delete[],在使用malloc 获得的所有内容上调用free

您还应该关闭您打开的所有套接字,并清除您的班级拥有的任何其他操作系统资源。

注意:这不叫垃圾回收。垃圾收集是当这个过程自动发生时,作为库或语言运行时的一部分,而不是当你明确地这样做时。

【讨论】:

    【解决方案4】:

    您应该从了解“资源获取即初始化”(RAII) 和智能指针(shared_ptrunique_ptr)开始。如果您来自其他语言,这是您必须了解的 C++ 习语

    通常的做法是,您在构造函数中分配的任何内容都必须在析构函数中释放(请参阅其他答案以了解如何)。事件更好,尽量使用值尽可能少new。 C++ 喜欢堆栈,堆栈分配和释放是自动且便宜的(无新建,无删除)。使用引用和常量引用而不是指针。

    如果您真的需要动态内存,请尝试使用其中一种智能指针。

    【讨论】:

      【解决方案5】:

      您使用 new 运算符分配的任何内存都需要被释放。

      你通过以下方式分配内存:

      int * p1 = new int[5];
      p2 = new int;
      

      然后你删除它:

      delete[] p1
      delete p2; 
      

      如果你在玩类,你需要在构造函数(分配)和析构函数(释放)中做同样的事情。

      【讨论】:

        【解决方案6】:

        在一个理想的世界里,什么都没有。每个模式都有智能指针和容器。有时,您必须自己编写或扩充现有实现,但您需要的大部分已经存在。

        对于数组,以std::arraystd::vector 开头。对于对象,请阅读智能指针和共享指针。作为一个概括:如果您需要致电deletedelete[]free,您通常会走错路。

        【讨论】:

          【解决方案7】:

          您需要垃圾收集不再需要的所有指针。否则你会遇到悬空指针问题。

          【讨论】:

          • C++ 没有垃圾收集。你和提问的人一样困惑。
          • 那不是悬空指针,那是内存泄漏。如果你释放它,然后尝试使用它,就会发生悬空指针。
          • 它的内存泄漏!,悬空是如果你删除然后尝试访问它!
          猜你喜欢
          • 1970-01-01
          • 2012-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-16
          • 1970-01-01
          • 1970-01-01
          • 2020-03-01
          相关资源
          最近更新 更多