在析构函数中需要删除

Is delete necessary in a destructor?

本文关键字:删除 析构函数      更新时间:2023-10-16

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

class A
{
    B *b;
    A()
    {
        b = new B();
    }
    ~A() 
    {
        delete b;
    }
};

非常感谢。

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

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

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

对动态所有涂层的对象使用智能指针总是一个好主意。这些会为你做所有删除的事情。

  • std::auto_ptr
  • boost::shared_ptr
  • boost::scope_ptr

这当然是您编写它的方式所必需的。不过,即使使用delete,该类也从根本上被破坏了,因为它管理资源,但不遵循三规则。

也就是说,几乎可以肯定的是,手动内存管理没有任何理由——很少有。很可能你应该只使用一个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.
};

你需要确保你有一本很好的C++入门书,这样你就可以学习如何编写正确的C++程序。

如果调用new,则建议始终进行相应的删除。

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

第三,只有在必要的时候才尝试使用new/delete。在你的场景中,你可以写

class A 
{
B b;
  A() {}
  ~A() {}
};

它将具有相同的效果,并且可以避免额外的动态内存分配。

它只会在进程结束时清除该区域,但在此之前,该区域将一直保持分配状态,这意味着内存泄漏。

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

因此,如果在分配的堆块未使用时(通常是在某个对象的析构函数中)不释放它们,那么就有内存泄漏的风险。

因此,答案基本上是:,您必须手动调用delete,因为内存不会自动释放(尽管智能指针可以帮助您实现类似的功能)。

资源管理不仅仅是释放内存。是的,当进程结束时,大多数平台都会产生你分配的任何内存,而且内存足够便宜,你可能一段时间都不会注意到。但是,保持打开状态的文件b,或者它将在其析构函数中解锁的互斥对象呢?在你的记忆力耗尽之前,你可能会遇到让你的物品过了使用寿命的问题。

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

在大多数现代操作系统(当然是人们通常在台式机上运行的操作系统)上,进程使用的任何东西都会在进程结束时被清理掉,所以如果你忘记了delete,那么内存无论如何都会被释放。然而,你不应该依赖这一点。

很久以前,我在C中的Amiga上编程。它的操作系统远没有今天的操作系统复杂。如果你分配内存而不释放它,它会一直被分配,直到你关闭或重新启动计算机,即使在这个过程结束之后。当时内存泄漏是一个更严重的问题。

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

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