在析构函数中是否需要删除?

时间:2011-06-28 06:52:21

标签: c++ memory-management

我有以下代码,我想知道这里是否需要delete b? 我的操作系统会自动清除分配的内存区域吗?

class A
{
    B *b;

    A()
    {
        b = new B();
    }

    ~A() 
    {
        delete b;
    }
};

非常感谢。

9 个答案:

答案 0 :(得分:12)

是的,您必须delete使用您拥有的new 创建的每个对象 。在这种情况下,看起来class A拥有class B的实例,并负责调用delete

使用智能指针管理class B实例生命周期会更好。另请注意,您必须在class A中实现或禁止赋值运算符和复制构造函数,以防止浅层复制对象,这会给您带来很多麻烦。

答案 1 :(得分:5)

您的操作系统可能会释放已分配的内存 - 但这可以在您的程序退出时完成。长时间运行的程序将遇到内存问题。

将智能指针用于动态涂层对象总是一个好主意。这些将为您完成所有删除操作。

  • 的std :: auto_ptr的
  • 升压:: shared_ptr的
  • 升压:: scoped_ptr的

答案 2 :(得分:2)

你写它的方式肯定是必要的。但是,即使使用delete,该类也会从根本上被破坏,因为它管理资源但不遵循the rule of three

也就是说,手动内存管理几乎肯定没有理由 - 很少有。您可能要么只有一个B对象作为成员变量,要么应该使用智能指针,如QScopedPointer

struct A
{
    QScopedPointer<B> b;
    A() : b(new B()) { }

    // No ~A() needed; when the A object is destroyed, QScopedPointer ensures 
    // that the B object pointed to by the member 'b' is destroyed and deleted.
};

您需要确保拥有a good introductory C++ book,以便学习如何编写正确的C ++程序。

答案 3 :(得分:2)

如果您拨打新电话,则始终建议进行相应的删除。

操作系统删除你的内存..是的,只有在整个过程终止后(即你的应用程序退出)才会发生。只有这样,操作系统才能回收所有内存和其他资源。

第三,尝试仅在必要时使用new / delete。在您的场景中,您可以编写

class A 
{

B b;

  A() {}

  ~A() {}

};

它会产生相同的效果,并且可以避免额外的动态内存分配。

答案 4 :(得分:1)

只有在流程结束时才会清除该区域,但该区域将一直保持分配状态,这意味着memory leak

答案 5 :(得分:1)

b成员将在堆上分配。确实,操作系统将释放堆占用的所有内存;但是这只会发生一次:程序退出

因此,如果你没有释放分配的堆块,那么它们就会被释放(通常在某个对象的析构函数中),你就有可能获得memory leak

所以答案基本上是:,你必须手动调用delete,因为内存不会自动释放(尽管智能指针会帮助你实现某些目标相似)。

答案 6 :(得分:1)

您使用new分配的任何内容都应该使用delete释放,否则您的应用程序中会出现内存泄漏。

在大多数现代操作系统(当然是人们通常在桌面计算机上运行的操作系统)上,当进程结束时,进程使用的任何内容都会被清除,所以如果你忘记了delete,那么内存将是无论如何都被释放了。但是你不应该依赖它。

很久以前我编写了C语言中的Amiga。它的操作系统远不如今天的操作系统复杂。如果您分配内存而不是释放它,它将保持分配状态,直到您关闭或重新启动计算机,即使在该过程结束后也是如此。内存泄漏是一个更严重的问题。

答案 7 :(得分:1)

资源管理不仅仅是释放内存。是的,大多数平台会在进程结束时生成你分配的任何内存,并且内存足够便宜,可能你暂时不会注意到。但是文件b保持打开状态,或者它将在析构函数中解锁的互斥锁呢?在内存不足之前,您可能会遇到让对象超出其实用性的问题。

答案 8 :(得分:0)

1)长时间运行的应用程序会遇到问题,因为操作系统只能在应用程序停止运行时回收内存。

2)delete b;也会导致指向B实例的析构函数运行。否则它永远不会运行,因为没有任何方法可以实现它。析构函数可能会做一些重要的事情。