我已经创建了一个代码块,就像这样。何时会释放内存?
proc()
{
Z* z = new Z();
}
现在在方法proc中声明的指针只有proc才会有作用域。我想问什么时候z的DTOR将被自动调用。无论何时控件从方法proc出来或当我的应用程序关闭时。
我已经创建了一个代码块,就像这样。何时会释放内存?
proc()
{
Z* z = new Z();
}
现在在方法proc中声明的指针只有proc才会有作用域。我想问什么时候z的DTOR将被自动调用。无论何时控件从方法proc出来或当我的应用程序关闭时。
DTOR不会自动调用。你应该使用“删除”关键字。
Z的析构函数将不会被调用,除非你把这样一行在你的代码:
delete z;
析构函数将根本不会被调用。*z
使用的内存将被泄漏,直到应用程序关闭(此时操作系统将收回您的进程所使用的所有内存)。
为避免泄漏,您必须在某个时间拨打delete
,或者更好的方法是使用智能指针。
除非您通过z
到delete
,否则您将发生内存泄漏。
这是内存泄漏。你可能应该拥有的是:
void
proc()
{
Z z;
}
并跳过动态分配。如果一个对象的生命周期对应于其范围 ,那么您很少需要动态分配。
如果由于某种原因,您确实需要动态分配(例如,因为多态性为 ),那么您应该使用某种智能指针; std::auto_ptr
在这里效果不错,而且像scoped_ptr
这样的东西,如果你有 有它们,可能会更好。
如果编译器支持它,那么最好使用unique_ptr,而你的scoped_ptr应该是类似的东西,但是不是标准的 – Geoffroy
@Geoffroy'unique_ptr'只是一个更新的'auto_ptr';如果你知道你永远不需要支持一个较老的编译器,你可以使用它。 'scoped_ptr'具有更多有限的语义,因为它不支持所有权的转移。 –
当你使用新的对象在堆上分配时,堆在你程序中的所有函数之间共享,也就是说你可以松散地说,堆分配对象的作用域是你的程序,所以不用做删除在对象上,它会存在,直到你的程序退出。
这是C++的基本原理之一。
动态分配
在你的情况,内存分配和随之而来的构造函数调用的Z
将发生在new
:
Z* z = new Z();
销毁和内存释放相反的一部分将发生在delete
:
delete z;
但是由于你的代码没有它,内存释放将永远不会发生,再加上你将失去指针z
,将来不会释放该对象。 这是典型的内存泄漏。
宣言
在另一方面,如果你声明的对象是这样的:
Z z;
内存分配和构造函数将被调用立即就在这里,在申报点,当对象存在范围已完成(即在函数结束时),析构函数将自动调用并释放内存。
动态分配VS宣言
我不会进入什么是好,什么是不争论,而是将提供摘自是下面链接的文章之一:
与将数据加载到程序数据段的声明不同,动态分配会在程序STACK(专门分配给该程序的RAM区域)上创建新的可用空间。
FYI:Stack = Performance,但not always the best solution。
参考
Java在Java中的基础如何?你的意思是“C++和Java之间的区别”吗? – Simon
谢谢,更新。经过少量修改后,第一句话就不再有效了。 –
在我已经声明* z的代码块中,我完成了它,所以我可以在返回proc语句之前调用“delete z”。 –
@Apoorva:如果您从不需要块外的'* z',则不应该使用动态分配。正如James Kanze写道的,只需使用'Z z;',当proc()返回时,对象将被销毁。 – MSalters