我曾经相信它确实可以,但是...我找不到它明确声明的内容。
man 3 exit
和man 2 _exit
详细指定了进程终止的效果,但没有提及内存泄漏。
Posix更近了:它提到了这一点:
在销毁进程之前,应先取消在进程中创建的内存映射。
[TYM] [Option Start]在调用过程中映射的任何类型的内存块都应被取消映射,就好像隐式调用
munmap()
来取消映射一样。 [选项结束]
将此与man 3 malloc
混合:
通常,
malloc()
使用sbrk(2)
从堆中分配内存,并根据需要调整堆的大小。当分配大于MMAP_THRESHOLD
个字节的内存块时,glibcmalloc()
实现使用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()
,并且仅在{{中调用exit
或error
1}}?
前者要简单得多。但是,为了轻松使用前者,我想在明确提到的文档中找到它,这不是错误,并且这样做很安全。就像我说的那样,文档确实要明确提及一些肯定会被清除的保证,但事实却没有提及这一具体保证,这令我感到不安。 (这不是最常见,最明显的情况吗?不是一开始就不会提到吗?)
答案 0 :(得分:7)
此“释放”是在内核级别完成的。因此,您不可能在POSIX API或C规范中找到任何直接内容,因为虚拟内存位于它们的下面。因此,您几乎找不到任何相关的信息-更不用说保证。
在Linux上,内核会在进程退出时(sbrk和mmap)回收内存,这是有保证的。参见source code of mm。
库调用失败时,我可以退出吗?
是的。很好。
但是,请注意,您可能还需要考虑其他注意事项,例如未清理的临时文件,打开的数据库/网络连接等。例如,如果程序使数据库连接保持打开状态并退出,则服务器端可能不知道何时关闭连接。
您可以阅读有关Virtual Memory Manager的更多信息(它基于较早的内核,但该思想仍然适用)。
答案 1 :(得分:7)
我确信POSIX委员会打算将malloc
分配的所有内存都作为与您链接的_exit
的规范中列出的“进程终止的后果”之一进行重新分配。我还可以告诉您,实际上,我使用过的Unix的每个实现都可以做到这一点。
但是,我认为您在规格中找到了真正的缺陷。 POSIX没有说任何关于sbrk
分配的内存的信息,因为它根本没有指定sbrk
。它对malloc
的规范是逐字逐句地从C标准中获取的,C标准故意并非说malloc
分配的所有内存都应该被释放。在“正常终止”状态下,因为存在嵌入式嵌入式环境无法执行此操作。而且,正如您所指出的,“在此过程中创建的内存映射”可以理解为仅适用于由mmap
,shmat
等直接进行的分配。向奥斯汀集团提出口译请求可能是值得的。