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

C++ 析构函数中是否需要删除?,c++,memory-management,C++,Memory Management,我有以下代码,我想知道这里是否需要删除b? 我的操作系统会自动清除分配的内存区域吗 class A { B *b; A() { b = new B(); } ~A() { delete b; } }; 非常感谢。是的,您必须删除使用新建创建的所有您拥有的对象。在这种情况下,它看起来像是class A拥有class B的实例,并负责调用delete 使用智能指针管理类B实例生命周期会更好。还要注意的是,

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

class A
{
    B *b;

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

    ~A() 
    {
        delete b;
    }
};

非常感谢。

是的,您必须
删除使用
新建
创建的所有您拥有的对象。在这种情况下,它看起来像是
class A
拥有
class B
的实例,并负责调用
delete


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

当然有必要采用您编写对象的方式。尽管如此,即使使用了
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.
};
结构A { QScopedPointer b; A():b(新b()){} //不需要~A();当A对象被销毁时,QScopedPointer确保 //成员“B”指向的B对象已销毁并删除。 };

你会想确保你可以学习如何编写正确的C++程序。

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

使用智能指针处理动态的所有对象总是一个好主意。这些将为您删除所有内容

  • 标准::自动测试
  • boost::共享\u ptr
  • boost::作用域\u ptr

仅当进程结束时才会清除该区域,但在此之前,该区域将一直保持分配状态,这意味着。

如果调用新的,则建议始终执行相应的删除操作

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

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

class A 
{

B b;

  A() {}

  ~A() {}

};

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

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

因此,如果您不在分配的堆块未使用时释放它们(通常是在某个对象的析构函数中),您就有可能得到一个新的堆块


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

任何使用
新建
分配的内容都应该使用
删除
释放,否则,应用程序中会出现内存泄漏

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


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

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

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

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