考虑这种情况:
dll = LoadDLL()
dll->do()
...
void do() {
char *a = malloc(1024);
}
...
UnloadDLL(dll);
此时,在调用 malloc() 时分配的 1k 是否再次可供宿主进程使用? DLL 静态链接到 CRT。
最佳答案
操作系统跟踪的进程使用的内存适用于整个进程,而不是特定于 DLL。
内存由操作系统以 block 的形式提供给程序,称为堆
堆管理器(malloc/new 等)进一步划分块并将其分发给请求代码。
只有在分配新堆时,操作系统才会检测到内存增加。
当 DLL 静态链接到 C 运行时库 (CRT) 时,CRT 的私有(private)拷贝以及 DLL 代码调用的 CRT 函数将被编译并放入 DLL 的二进制文件中。 Malloc也包含在这里面。
只要静态链接的 DLL 中存在的代码尝试分配内存,就会调用 malloc 的私有(private)拷贝。
因此,此 malloc 从操作系统获取一个仅对 malloc 拷贝可见的私有(private)堆,并在该私有(private)堆内分配代码请求的内存。
当 DLL 卸载时,它会卸载其私有(private)堆,当整个堆返回给操作系统时,这种泄漏不会被注意到。
但是,如果 DLL 是动态链接的,则内存由单个共享版本的 malloc 分配,全局分配给以共享模式链接的所有代码。
此全局 malloc 分配的内存来自一个堆,该堆也是用于所有其他代码的堆,这些代码以动态 aka 共享模式链接,因此很常见。因此,来自该堆的任何泄漏都会成为影响整个过程的泄漏。
编辑 - 添加了链接场景的描述。
关于c++ - 卸载 DLL 时的内存泄漏是否会导致主机进程发生泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/132242/