考虑这种情况:
dll = LoadDLL() dll->do() ... void do() { char *a = malloc(1024); } ... UnloadDLL(dll);
此时,在调用malloc()时分配的1k是否可以再次用于主机进程?DLL静态链接到CRT.
由OS跟踪的进程使用的内存适用于整个进程,而不是特定于DLL.
内存由操作系统以块的形式提供给程序,称为堆
堆管理器(malloc/new等)进一步划分块并将其交给请求代码.
只有在分配了新堆时,操作系统才会检测到内存增加.
当DLL静态链接到C运行时库(CRT)时,将编译具有DLL代码调用的CRT函数的CRT的私有副本并将其放入DLL的二进制文件中.Malloc也包括在内.
只要静态链接的DLL中存在的代码尝试分配内存,就会调用malloc的私有副本.
因此,通过此malloc从OS获取仅对此malloc副本可见的私有堆,并且它分配此私有堆中的代码所请求的内存.
当DLL卸载时,它会卸载它的私有堆,并且当整个堆返回到操作系统时,这个泄漏就会被忽略.
但是,如果动态链接DLL,则内存由malloc的单个共享版本分配,全局到共享模式中链接的所有代码.
由此全局malloc分配的内存来自堆,该堆也是用于在动态aka共享模式中链接的所有其他代码的堆,因此是常见的.因此,来自该堆的任何泄漏都会成为影响整个过程的泄漏.
编辑 - 添加了链接方案的说明.
你不能说.这取决于静态和动态CRT的实现.它甚至可能取决于分配的大小,因为有CRT将大量分配转发给OS,但是为小分配实现自己的堆.
CRT泄漏的问题当然是泄漏.CRT不泄漏的问题是可执行文件可能合理地期望使用内存,因为malloc的内存应该保持可用,直到调用free.