退出前我应该释放内存吗?

Luc*_*fia 20 c malloc free dynamic-allocation

因错误而退出程序时,我应该释放所有的mallocated内存吗?

something = (char**) malloc (x * sizeof(char*));
for (i = 0; i < x; i++)
    something[i] = (char*) malloc (y + 1);

...

if (anything == NULL) {
   printf("Your input is wrong!");
   // should I free memory of every mallocated entity now?
   exit(1);
} 
else {
   // work with mallocated entities
   ...
   free(something); // it must be here
   system("pause);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*mit 18

这实际上是一个非常困难,无法估量的问题.

Pro(支持在退出前释放所有内容):

  • 如果重新安排代码,以后不会出现错误或内存泄漏
  • valgrind或内存泄漏检查器没有误报
  • 如果你在一个有缺陷的操作系统下运行,或者根本没有操作系统,则没有内存泄漏

Con(只需退出,不要担心释放一切):

  • 释放一切可以做很多工作
  • 释放一切可以引入错误和崩溃
  • 你的操作系统确实应该在退出时为你收回所有资源

最后,您必须决定哪些优点和缺点对您最重要.不同情况下不同项目的不同程序员会得出不同的结论; 这里没有一个通用的答案.

另见C FAQ列表中的问题7.24.

  • 说得好!重申我在下面发表的评论:如果你是一个新手,一般来说,让“手动释放”成为习惯本能(不太危险的习惯),并让“把它留给操作系统”成为一个有意识的、知情的、逐案的-案件决定。随着时间的推移,为此的决策过程将成为本能。否则,您将习惯性地忘记释放您的 malloc 并清理您的悬空指针,并且您随后在下次更改代码时注册惊喜 UB,以至于现在无法释放内存*很重要*。 (4认同)
  • 正如我在另一个(更长的)评论链中所说:答案中的链接支持我的观点。总的来说,**手动释放**(总体而言,不仅仅是在程序结束时)通常是稳定性问题(短期和长期),而**不手动释放**通常是性能问题,并且我们都知道一句格言:“过早优化是万恶之源”。(-唐纳德·克努斯)。**习惯自由,决定不做选择,**不是为了保证OS取回内存,而是为了防止以后重构代码时出错。除此之外,我们还有一场“圣战”,可能最好同意不同意。 (2认同)

fuz*_*fuz 10

在程序终止之前,您不需要释放内存.以任何方式终止程序会导致所有内存自动解除分配.

  • 在具有适当进程隔离的托管环境中,忽略共享内存之类的东西...... (6认同)
  • @JasonMc92我不同意.在错误退出时,由于数据结构可能已损坏,因此通常很难或无法正确清理所有内存.试图清理东西是徒劳的. (3认同)
  • 我想对这个答案进行投票,因为这些是最终会咬我们的东西.我没有,但我想. (2认同)
  • 我想我所说的是:我们需要**默认为手动清理**,并在适当的时候做出有意识的决定将其留给操作系统.如果我们默认"让操作系统使用它"并且必须有意识地决定清理自己,我们更有可能"忘记"导致悬挂指针之类的东西(特别是在代码重写期间),从而产生瑞银(UBS).**不要手动清理的决定需要是一个受过教育的有意选择*,因为我确信这是习惯性的.经验不足的程序员需要**形成这种习惯. (2认同)
  • 当然,形成这种习惯的方法是习惯性地在可能的情况下计划手动清理,当他们意识到这将是困难/不切实际/危险时,做出有意识的决定"我最好把它留给操作系统来清理"起来.对于相反的习惯,许多新手编码器将决定"我不需要释放我的malloc.操作系统会这样做!" 并且没有注意到他们要求五行之后的一群鼻子恶魔. (2认同)
  • 不必要和无根据的显式释放是过早停止。 (2认同)

Lun*_*din 7

在退出之前,应始终释放已分配的内存.正如其他答案中已经提到的,这将最大限度地减少静态或动态分析工具等的警告.

但是你应该总是这样做的真正原因是因为释放经常暴露应用程序中的休眠运行时错误.

如果某个地方有一个导致内存损坏或更改指针地址的错误,那么该错误可能会保持沉默并处于休眠状态.直到你改变与bug完全无关的东西,从而改变内存布局.然后你突然崩溃了,你也不知道为什么,因为这个bug甚至没有出现在你刚添加的代码中.

通过释放内存,你会引发这样的错误.因为如果堆有任何问题或者指针指向堆,那么你经常会在你调用的地方崩溃free().这意味着您在运送程序之前需要找到一个严重的错误.


Har*_*rry 6

这取决于操作系统。最佳实践是,您应该明确释放它。如果您没有在整个地方释放内存,并且我无法分辨出什么是好的和坏的,它也使使用valgrind这样的工具成为PITA。

如果在明确释放内存的操作系统上,您仍然会遇到其他资源问题。随着您的应用程序开始增长并引入第三方库,您可能会遇到资源泄漏的情况。想象一下,我已经编写了一个库,要求您在处理程序上调用close。除非您调用close,否则该处理程序恰好由不会被删除的临时文件支持。或者,我已经使用信号或您不知道的其他资源分离了在后台运行的进程,这些进程正在管理中。

  • 处理临时文件的方法是在运行时删除它们,而不是在关机时删除它们。随时可能断电,而完全依赖关机程序的应用程序将会遇到麻烦。 (4认同)
  • 程序终止后,哪些系统无法释放内存? (2认同)
  • @MartinJames 两者都做?不要留下任何混乱,抵制原则等等 (2认同)