【问题标题】:Does this program have a memory leak? [duplicate]这个程序有内存泄漏吗? [复制]
【发布时间】:2013-03-01 09:25:33
【问题描述】:
int main()
{
    char *a = malloc(1024);
    return 0;
}

上面的程序有内存泄漏吗?请提供尽可能完整和技术性的答案。

【问题讨论】:

  • 取决于你问谁...有些人不认为这是泄漏。
  • @Inisheer,我不是在问内存是否被释放 :) 我是在问这是否是内存泄漏。
  • @gg.kaspersky 内存未释放是泄漏。在这种情况下,您似乎很好奇应用程序退出后内存泄漏是否仍然存在。
  • @Inisheer,根据一些消息来源,泄漏被认为是您无法再访问分配的内存的情况。
  • @gg.kaspersky 正确。因此,如果 char* 在应用程序退出后仍然被分配,那么它可能会被认为是泄漏。但是,在我发布的链接中,它详细介绍了应用程序退出时如何释放内存(在大多数情况下)。我知道你来自哪里,但例子是相关的。

标签: c memory-leaks


【解决方案1】:

程序本身有泄漏。操作系统是否清除它是另一回事。我想最好问“这个程序可能会导致任何系统出现问题吗?”答案是肯定的。

C 标准没有规定使用malloc 分配的内存将在程序终止时释放,无论是正常还是异常。将其与打开的文件进行比较,如果程序正常终止,C 实现会保证为您关闭这些文件。

【讨论】:

  • 我认为这是最明确的答案(也是正确的)。
  • @gg.kaspersky:用valgrind 演示很容易,它(在一定程度上)模拟了在程序执行后不会清理的计算机和操作系统。它会报告它在运行您的程序时永久丢失了 1,024 个字节。
【解决方案2】:

简单的答案是肯定的。操作系统正在为你整理

编辑

为了 gg.kaspersky 的利益。

当程序结束时,您应该整理堆。它表示您已经考虑了所有分配并提供了这些资源的释放(对于打开的文件或其他操作系统资源可以说是这样)。

这对你来说够复杂吗?

顺便说一句 - 访问家庭 (OS) 时,您将其保持与到达时相同的状态是一种礼貌。

【讨论】:

  • 我正在寻找复杂的答案。
  • @gg.kaspersky 请参阅 cmets 部分中的链接。
  • +1 - The OS is - 至少你希望是这样。就像您在致电 free 时所说的“为什么要让事情变得复杂”一样,您知道您已经放下了那段记忆。
  • @mike - 它还告诉正在审查您的代码(或使用它)的人您已经考虑了所有角度
【解决方案3】:

您的问题不完整...因此,您可以获得的最佳答案是“视情况而定”。

从程序范围来看,是的,您有内存泄漏。这应该是显而易见的。从系统范围来看,答案取决于您在哪个操作系统上运行。

一般来说,如果您是在主流设备(Win7/MacOSX/Linux 台式机/笔记本电脑、iOS/Android 设备等)上编程,那么您是非常安全的。我想不出任何主流现代操作系统都无法在你之后进行清理。

但是,如果您使用的是一些较旧的或嵌入式系统,您在此处泄漏内存。我在 uCLinux 平台(专为没有 MMU [内存管理单元] 的硬件设计的操作系统)上看到了内存泄漏。

动态内存通常被认为是危险的,这就是为什么在某些 RTOS 上使用它是不合法的。如果您知道应用程序在整个使用生命周期内的部署范围,那么您可以编写这样的代码……但您很可能不知道,您不应该对操作系统会做什么做出假设.总是清理自己的烂摊子。

【讨论】:

  • 我同意我的问题是不完整的,它错过了内存泄漏的定义。
  • @gg.kaspersky - 是的,但更重要的是,操作系统是什么?我认为这是一个安全的假设,即内存泄漏是“只能通过系统的电源循环恢复的不可访问的 RAM 地址范围”,并且(根据我的回答)一些操作系统可以在它引起问题之前捕获/释放它,一些可以't。
【解决方案4】:

我不会认为这是内存泄漏。退出时仍可通过仍在作用域内的变量访问内存。

在程序结束时释放您分配的所有内存只是不必要的迂腐,让您花时间做操作系统会更有效地为您做的事情。

编辑(技术细节):

对于 malloc 的某些实现,在程序结束时进行不必要的内存释放可能会非常低效。所有保持其会计信息内联(通过边界标记或类似机制)的 malloc 实现将触及您已分配的大部分(如果不是全部)页面。通常,除了弄脏缓存行和被丢弃的 TLB 条目之外,这不是问题,但是将此与使用足够内存来开始使用交换的程序相结合,最终您会交换大量内存以释放它。当您退出时,操作系统可以更有效地执行此操作(只需将交换槽标记为空闲)。

如果您有一个将内存返回给操作系统的 malloc 实现,则释放内存将导致操作系统取消映射内存,如果您在多处理器系统上,这又需要昂贵的 TLB 操作。在退出时,可以更有效地进行失效(通过执行完整的 TLB 刷新或使 TLB 标记失效)。

【讨论】:

  • 这是一个见仁见智的问题(在我看来......)。如果将来您的应用程序被转换为库(这种情况经常发生),您现在必须仔细检查并找出所有需要清理的地方。所以你不妨一开始就这样做。
  • 考虑分配的内存是否包含对操作系统资源的引用(例如,文件描述符到套接字等)。这会告诉我,如果你没有取消分配包含该描述符的内存,它会告诉我程序员没有关闭套接字,即客户端/服务器仍然挂起。
  • @OliCharlesworth,我说得对吗,忽略“良好的编码实践”的东西,程序(在现代 linux 操作系统上运行)不会造成任何问题?
  • “在一些 malloc 的实现中,在程序结束时不必要地释放内存可能会非常低效” - 参考您为什么说这是真的?
  • @OliCharlesworth 当然。但我正在回答被问到的问题,而不是假设的问题。通过消除程序末尾的迂腐释放内存,我实际上将程序的执行时间缩短了几分钟。此外,在操作系统级别处理内存管理(包括进程的退出路径)后,我知道在操作系统中直接对整个事物进行核对而不是从用户空间进行操作要便宜得多。
猜你喜欢
  • 2016-08-27
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多