以下是我的代码,我想知道这里的 delete b
是否必要?我的操作系统会自动清除分配的内存区域吗?
class A
{
B *b;
A()
{
b = new B();
}
~A()
{
delete b;
}
};
非常感谢。
以下是我的代码,我想知道这里的 delete b
是否必要?我的操作系统会自动清除分配的内存区域吗?
class A
{
B *b;
A()
{
b = new B();
}
~A()
{
delete b;
}
};
非常感谢。
是的,您必须删除
您拥有的每个使用new
创建的对象。在此情况下,似乎class A
拥有该class B
的实例并负责调用delete
。
最好使用智能指针来管理class B
实例的生命周期。另外请注意,在class 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.
};
您需要确保拥有一本好的C++入门书籍,以便学习如何编写正确的C++程序。
如果你调用了new,相应的delete是必须的。
至于操作系统删除内存,是的,它会发生,但只有在整个进程终止(即你的应用程序退出)后才会发生。只有在此之后,操作系统才会回收所有内存和其他资源。
第三点,尽可能只在必要时使用new/delete。在你的情况下,你可以直接写
class A
{
B b;
A() {}
~A() {}
};
b
成员将在堆上分配。操作系统确实会释放堆占用的所有内存;但是这只会发生一次:在程序退出时。
因此,如果您不在它们变得无用的那一刻(通常在某个对象的析构函数中)释放已分配的堆块,则有可能出现内存泄漏。
所以基本答案是:是的,您必须手动调用delete
,因为内存不会立即自动释放(尽管智能指针可以帮助您实现类似的功能)。
使用new
分配的任何内容都应该使用delete
释放,否则您的应用程序中会存在内存泄漏。
在大多数现代操作系统上(特别是人们通常在桌面计算机上运行的操作系统),进程使用的任何内容都将在进程结束时清除,因此如果您忘记了delete
,那么内存将被自动释放。但是,您不应该依赖于这一点。
很久以前,我在C语言中编写Amiga的程序。它的操作系统比今天的操作系统要简单得多。如果您分配了内存并没有释放它,在关闭或重新启动计算机之前,它将保持分配状态,即使进程已经结束。当时,内存泄漏问题更加严重。
资源管理不仅仅是释放内存。是的,大多数平台会在进程结束时释放您分配的任何内存,而且内存足够便宜,也许您一段时间内都不会注意到。但是,如果文件b正在打开,或者互斥量将在其析构函数中解锁,那么怎么办?在耗尽内存之前,您可能会遇到让对象超出其有用性的问题。
1) 长期运行的应用程序会遇到问题,因为操作系统只能在应用程序停止运行时收回内存。
2) delete b;
也会导致所指向的B实例的析构函数运行。否则,它将永远不会运行,因为再也无法访问它了。那个析构函数可能会执行一些重要操作。