【问题标题】:what happens to malloc?malloc 会发生什么?
【发布时间】:2014-05-03 10:36:28
【问题描述】:

好吧,我想我知道问题的答案,但我更放心。如果你在堆上 malloc 内存并在释放空间之前退出程序,操作系统或编译器会为你释放空间吗?

【问题讨论】:

  • 现代操作系统会在程序终止后释放内存。
  • 操作系统必须这样做。编译器不能这样做,因为它不存在。它生成的应用程序代码无法执行此操作,因为它可能已经崩溃或刚刚卡住并被 kill-9 或任务管理器强行终止。
  • 也可能是该应用程序甚至没有设计为尝试执行此操作,因为它的工作太复杂了,操作系统只需一次调用即可完全正确地完成它。

标签: c malloc


【解决方案1】:

当操作系统从其进程列表中删除进程的描述符(在 Linux 的情况下为task_struct)时,操作系统会为您释放空间。

编译器通常会生成一个exit() 系统调用,并在那里处理所有这些。

在 Linux 上,基本上,所有这些都发生在内核的 exit_mm() 函数中,最终由 exit() 调用。它将通过mm_release()函数释放进程所拥有的地址空间。所有这些源代码都可供您阅读(尽管它可能会变得有点复杂:) 但是是的,操作系统负责释放进程的资源。

因为我非常喜欢它,如果你喜欢这些主题,这是一个非常好的阅读:Understanding the Linux Kernel

【讨论】:

    【解决方案2】:

    这超出了 C 标准的范围。发生什么取决于系统。在所有常见的主流操作系统上,操作系统都会在进程完成后释放内存。

    不过,始终清理自己的烂摊子是个好习惯。因此,无论操作系统做什么,您都应该始终释放您正在使用的所有资源。这样做也是发现隐藏的运行时错误的好方法:如果您有错误,当您尝试释放资源时程序可能会崩溃,从而提醒程序员注意错误。

    至于编译器,它只在程序创建期间有效,与程序的运行时执行完全无关。

    【讨论】:

    • '所以无论操作系统做什么,你都应该释放你正在使用的所有资源'——不,不是真的。在没有必要的情况下尝试这样做意味着编写更多代码。编写更多代码意味着编写更多错误、调试更多错误和更多测试。在没有必要这样做的情况下,编写更多代码来“彻底关闭”复杂的多线程系统是不合理的。
    • @MartinJames 如果您的复杂多线程系统不能轻易关闭,我会说这表明程序设计不佳。如果您遇到“我自己的代码如此复杂以至于我不知道它在做什么,更不用说如何停止它了。救命!紧急停止在哪里!?”......我会说你有一个很差程序设计。此外,在线程的特定情况下,活线程可能会导致进程在应该死的时候仍然像幽灵一样运行。
    • @MartinJames:不能干净关闭的程序是查找内存泄漏等缺陷的障碍;内存泄漏检测器将被误报淹没。但是你是对的,在拆除建筑物之前扫地没有什么意义。我鼓励两者都做:编写代码以清理正常关机程序,并愿意在异常关机的情况下匆忙放弃一切。见stackoverflow.com/questions/15488099/why-do-i-need-to-delete/…
    • @Lundin 我的“设计不佳”的多线程系统(即,那些没有不必要的显式关闭代码的系统)都可以正常工作,并且在请求时它们都会立即关闭。我的代码不一定“太复杂”,只是我不知道它在任何时候都在做什么。数据以不确定的消息流和缓冲区流向各处,这就是为什么在任何时候都无法轻松了解正在发生的事情,因此难以设计和实施高效的关闭系统。
    • 另外,' '活动线程可能会导致进程像幽灵一样继续运行' - 什么活动线程?从任何线程终止进程请求操作系统在释放进程资源之前停止所有内核上的所有线程,无论它们处于什么状态。用户代码无法在任何状态下停止所有线程 - 它无权访问停止在另一个内核上运行的线程所需的内核间驱动程序。如果说有什么“设计不佳”,那就是应用程序使用了不必要的、过于复杂和有问题的关闭代码,而不是依赖于经过数十年测试的操作系统。
    【解决方案3】:

    操作系统会清除程序消耗的所有资源,包括所有分配的内存、网络连接、文件句柄等。

    【讨论】:

      猜你喜欢
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 2013-07-29
      • 1970-01-01
      • 2011-08-08
      相关资源
      最近更新 更多