在C ++中,当您在堆上创建一个新变量时:
int* a = new int;
你可以通过使用delete来告诉C ++回收内存:
delete a;
但是,当你的程序关闭时,它会自动释放用new分配的内存吗?
答案 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不会有问题,当然; - )。