Memory leaks Linux是否保证释放malloc';d程序退出时是否取消缠绕内存?

Memory leaks Linux是否保证释放malloc';d程序退出时是否取消缠绕内存?,memory-leaks,malloc,posix,language-lawyer,terminate,Memory Leaks,Malloc,Posix,Language Lawyer,Terminate,我曾经相信这是肯定的,但是。。。我找不到明确的说明 详细说明进程终止的影响,但不要提及内存泄漏 更接近:它提到: 在进程中创建的内存映射应在进程销毁之前取消映射 [TYM][Option Start]调用过程中映射的任何类型化内存块都应取消映射,就像隐式调用munmap()来取消映射一样。[选项结束] 这与: 通常,malloc()使用sbrk(2)从堆中分配内存,并根据需要调整堆的大小。当分配大于MMAP_阈值字节的内存块时,glibcmalloc()实现使用MMAP(2)将内存分配为

我曾经相信这是肯定的,但是。。。我找不到明确的说明

详细说明进程终止的影响,但不要提及内存泄漏

更接近:它提到:

  • 在进程中创建的内存映射应在进程销毁之前取消映射

  • [TYM][Option Start]调用过程中映射的任何类型化内存块都应取消映射,就像隐式调用
    munmap()
    来取消映射一样。[选项结束]

这与:

通常,
malloc()
使用
sbrk(2)
从堆中分配内存,并根据需要调整堆的大小。当分配大于
MMAP_阈值
字节的内存块时,glibc
malloc()
实现使用
MMAP(2)
将内存分配为私有匿名映射

所以我们可以得出结论,如果
malloc
调用
mmap
,那么进程终止可能会相应地调用
munmap
,但是。。。(a) 这个POSIX规范中的“可选特性”标签有点令人担忧,(b)这是
mmap
,但是
sbrk
呢?(c) Linux不是100%符合POSIX规范的,所以我不确定是否强制要求将Linux docu与POSIX规范混合使用

我问的原因是。。。当库调用失败时,是否允许我退出

if(somecall() == -1) {
    error(EXIT_FAILURE, errno, "Big fat nasty error.\n");
}
或者,我必须在堆栈上确保一直到
main()
的所有内容都是
free()
'd,并且只在
main()
中调用
exit
error

前者要简单得多。但是为了更容易理解前者,我想在文档中明确提到这不是一个错误,这样做是安全的。正如我所说,文件中明确提到了一些肯定会得到清理的保证,但没有提到这一具体保证,这一事实让我感到不安。(这难道不是最常见、最明显的情况吗?首先不提一下吗?

这种“释放”是在内核级别完成的。因此,您不太可能在POSIXAPI或C规范中直接找到任何内容,因为虚拟内存远远“低于”它们。所以你几乎找不到任何相关的东西——更不用说保证了

在Linux上,内核在进程退出时回收内存(sbrk和mmap),这是有保证的。看

当库调用失败时,是否允许我退出

if(somecall() == -1) {
    error(EXIT_FAILURE, errno, "Big fat nasty error.\n");
}
对。这样做很好

但是,请注意,可能还需要考虑其他因素,例如未清理的临时文件、打开的数据库/网络连接等。例如,如果您的程序保持数据库连接打开并退出,服务器端可能不知道何时关闭连接


您可以阅读更多信息(它基于较旧的内核,但这个想法仍然适用)。

我确信POSIX委员会打算将
malloc
分配的所有内存作为您链接到的
\u exit
规范中列出的“进程终止的后果”之一进行释放。我还可以告诉您,在实践中,我使用过的每个Unix实现都做到了这一点


然而,我认为您已经在规范中发现了真正的漏洞。POSIX没有说明由
sbrk
分配的内存,因为它根本没有指定
sbrk
。它对
malloc
的规范或多或少是从C标准中一字不差地取出来的,C标准故意不说
malloc
分配的所有内存都应该在“正常终止”时释放,因为存在不这样做的嵌入式环境。而且,正如您所指出的,“在过程中创建的内存映射”可以被读取为仅适用于由
mmap
shmat
等直接进行的分配。向Austin Group提交一个解释请求可能是值得的。

调用exit将最终释放内核中被放弃进程的所有私有匿名内存。你怎么会认为Linux不能做到这一点?@karimanaouil我怎么想的?听着,我不知道Linux在幕后是如何工作的。我只是一个n00b,他已经制定了一条规则,永远不要做任何他没有被明确告知他可以做的事情。我认为,当我处理C++、C、系统调用等时,这种方法是有意义的,因此,当环境在最不直观的地方被各种各样的行为定义时,基本上是这样。“哦,这一定行得通,我无法想象这怎么会行不通”的方法已经折磨了我,所以我希望从现在开始保持安全。在这方面,我完全同意你的看法。当你问这样的问题时,关于每个人都希望以特定方式工作的事情是否真的能够按照相关标准以这种方式工作,这有助于将问题标记为“语言律师”。@zwol和我做到了!但这是第五个标签。然后我想把它也贴上“malloc”标签是有道理的。但我必须删除一个现有的标签才能这样做。“语言律师”是我的选择。我仍然希望“laguange律师”被包括在内,但我不确定要放弃哪些现有的标签。关于C的要点很重要:标准有时是故意允许的,所以这可能真的是两种情况。@alexis是的。C在这里是故意允许的。不过,我不认为POSIX是有意的。