在析构函数中需要删除
Is delete necessary in a destructor?
我有以下代码,我想知道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的实例的析构函数运行。否则,它将永远不会运行,因为再也没有任何方法可以访问它了。那个析构函数可能会做一些重要的事情。
- MSVC 编译器/链接器何时合成标量/矢量删除析构函数
- 如果引用应该保留,不删除析构函数中的指针会导致内存泄漏吗?
- 删除析构函数C++中的指针
- bad_alloc::'标量删除析构函数'(无符号整数)当我尝试创建矢量 470MB 大小时
- 这是删除析构函数中的数组的正确方法吗?
- 尽管使用了 boost::scoped_ptr,我们是否应该删除析构函数中成员的指针
- 调用remove()删除析构函数中的文件是否安全
- 当存储在std::vector属性中时,我可以删除析构函数中的指针吗
- 删除析构函数中的(这个)指针
- C++ 删除析构函数中的向量类成员内存
- 删除析构函数中的指针和映射
- 尝试删除析构函数中已删除的指针
- 为什么允许我声明一个带有已删除析构函数的对象
- 为什么在删除析构函数时调用析构函数,如果未删除则不调用析构函数?
- 删除析构函数的意义何在
- std::istream子类:删除析构函数中的streambuf
- 如何安全地删除析构函数中的线程指针
- 标量删除析构函数问题
- C++11:我可以创建一个类型具有已删除析构函数的字段吗
- 为什么在 VC 中,'delete' 和 'delete []' 都使用标量删除析构函数?