释放动态分配的内存

时间:2010-07-18 16:48:34

标签: c++ memory dynamic allocation

在C ++中,当您在堆上创建一个新变量时:

int* a = new int;

你可以通过使用delete来告诉C ++回收内存:

delete a;

但是,当你的程序关闭时,它会自动释放用new分配的内存吗?

6 个答案:

答案 0 :(得分:6)

是的,它会被自动回收,但是如果你打算编写一个大量使用堆而不是在任何地方调用delete的程序,你必然会快速耗尽堆内存,这会崩溃你的计划。

因此,必须谨慎管理您的内存并释放动态分配的数据,每delete匹配new(如果使用delete [],则为new []),一旦你不再需要上述变量。

答案 1 :(得分:3)

当进程终止时,操作系统将回收内存。当然,在任何情况下都不应该使用该参数来不对程序执行适当的内存管理。

答案 2 :(得分:2)

不要让别人告诉你是的。 C ++没有操作系统的概念,所以说“是的操作系统会清理它”不再是在谈论C ++,而是关于在某些环境中运行的C ++,这可能不是你的。

也就是说,如果你动态地分配了一些但从未释放它的东西,那你就泄露了。一旦您致电delete / delete[],它就只能终止其生命周期。在某些操作系统(以及几乎所有桌面操作系统)上,内存将被回收(因此其他程序可能会使用它。)但内存与资源相同!操作系统可以释放它想要的所有内存,如果你有一些套接字连接关闭,一些文件完成写入等,操作系统可能不会这样做。重要的是不要让资源泄漏。我听说过一些嵌入式平台甚至无法回收你没有释放的内存,导致漏洞直到平台重置。

不是动态分配原始的东西(意味着你是必须明确删除它的东西),而是将它们包装成自动分配的(堆栈分配的)容器;不这样做被认为是不好的做法,并使你的代码非常混乱。

所以不要使用new T[N],请使用std::vector<T> v(N);。后者不会让资源泄漏。请勿使用new T;,请使用smart_ptr p(new T);。智能指针将跟踪对象并在知道更长时间时将其删除。这称为范围限制资源管理(SBRM,也称为数字名称资源获取是初始化,或RAII。)

请注意,没有单个“smart_ptr”。你必须选择哪一个是最好的。目前的标准包括std::auto_ptr,但它非常笨拙。 (它不能用在标准容器中。)最好的办法是使用Boost的智能指针部分,如果编译器支持它,则使用TR1。然后你得到shared_ptr,可以说是最有用的智能指针,但还有很多其他指针。

如果每个指向动态分配的内存的指针都在一个将要破坏的对象中(即,不是另一个动态分配的对象),并且该对象知道释放内存,则保证释放该指针。这个问题甚至不应成为一个问题,因为你永远不应该泄漏。

答案 3 :(得分:1)

不,你有责任释放它。此外,a必须是指针,因此它应该是:

int *a = new int;
delete a;

excellent answer by Brian R. Bondy详细说明为什么释放a分配的内存是一种好习惯。

  

明确调用很重要   删除,因为您可能有一些代码   在你想要的析构函数中   执行。就像写一些数据一样   到日志文件。如果你让操作系统免费   你的记忆,你的代码   析构函数不会被执行。

     

大多数操作系统都会解除分配   程序结束时的内存。但   解除分配是一种好习惯   你自己,就像我在OS上面所说的那样   不会打电话给你的析构函数。

     

至于调用删除一般,是的   你总想打电话给删除,或   否则你会有内存泄漏   你的计划,这将导致新的   分配失败。

答案 4 :(得分:1)

不,当程序退出(“关闭”)时,动态分配的内存保持原样

编辑:

阅读其他答案,我应该更精确。动态分配的对象的析构函数不会运行,但任何体面的操作系统都会回收内存。

PS:第一行应该是

int* a = new int;

答案 5 :(得分:0)

当您的流程终止时,操作系统会重新控制流程正在使用的所有资源,包括内存。然而,当然,这不会导致C ++的析构函数必然运行,因此它不是没有明确释放所述资源的灵丹妙药(尽管对int或其他类型的noop dtors不会有问题,当然; - )。