我曾经相信这是肯定的,但。。。我找不到明确的说明。
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文档与POSIX规范混合在一起
我问的原因是。。。当图书馆呼叫失败时,我可以直接退出吗?
if(somecall() == -1) {
error(EXIT_FAILURE, errno, "Big fat nasty error.n");
}
还是我必须向上堆栈,确保一直到main()
的所有内容都是free()
'd,并且只在main()
中调用exit
或error
?
前者要简单得多。但为了方便使用前者,我希望在文档中明确提到这不是错误,这样做是安全的。正如我所说,事实上,文件明确提到了一些肯定会被清理的保证,但没有提到这个具体的保证,这让我感到不安。(这不是最常见和最明显的情况吗?这不是一开始就提到的吗?(
这个"释放"是在内核级别完成的。因此,您不太可能在POSIX API或C规范中找到任何直接的东西,因为虚拟内存远远"低于"它们。因此,您几乎找不到任何相关的东西,更不用说保证了。
在Linux上,内核在进程退出时回收内存(sbrk和mmap(,这是有保证的。参见毫米的源代码
当库调用失败时,是否允许我退出?
是。这样做很好。
但是,请注意,您可能还需要考虑其他因素,如未清理的临时文件、打开的数据库/网络连接等。例如,如果您的程序打开数据库连接并退出,服务器端可能不知道何时关闭连接。
您可以阅读更多关于虚拟内存管理器的内容(它基于旧的内核,但这个想法仍然适用(。
我确信POSIX委员会打算将malloc
分配的所有内存作为您链接到的_exit
规范中列出的"进程终止的后果"之一进行释放。我还可以告诉您,在实践中,我使用过的每一个Unix实现都做到了这一点。
然而,我认为您在规范中发现了一个真正的缺陷。POSIX没有说明sbrk
分配的内存,因为它根本没有指定sbrk
。它对malloc
的规范或多或少地取自C标准,而C标准有意地并没有说malloc
分配的所有内存都应该在"正常终止"时释放,因为存在不这样做的嵌入式环境。而且,正如您所指出的,"在此过程中创建的内存映射"可以被读取为仅适用于mmap
、shmat
等直接进行的分配。可能值得向奥斯汀集团提出解释请求。