c++ - 卸载 DLL 时的内存泄漏是否会导致主机进程发生泄漏?

标签 c++ winapi dll memory-management crt

考虑这种情况:

dll = LoadDLL()
dll->do()

...
void do() {
    char *a = malloc(1024);
}
...

UnloadDLL(dll);

此时,在调用 malloc() 时分配的 1k 是否再次可供宿主进程使用? DLL 静态链接到 CRT。

最佳答案

  1. 操作系统跟踪的进程使用的内存适用于整个进程,而不是特定于 DLL。

  2. 内存由操作系统以 block 的形式提供给程序,称为堆

  3. 堆管理器(malloc/new 等)进一步划分块并将其分发给请求代码。

  4. 只有在分配新堆时,操作系统才会检测到内存增加。

  5. 当 DLL 静态链接到 C 运行时库 (CRT) 时,CRT 的私有(private)拷贝以及 DLL 代码调用的 CRT 函数将被编译并放入 DLL 的二进制文件中。 Malloc也包含在这里面。

  6. 只要静态链接的 DLL 中存在的代码尝试分配内存,就会调用 malloc 的私有(private)拷贝。

  7. 因此,此 malloc 从操作系统获取一个仅对 malloc 拷贝可见的私有(private)堆,并在该私有(private)堆内分配代码请求的内存。

  8. 当 DLL 卸载时,它会卸载其私有(private)堆,当整个堆返回给操作系统时,这种泄漏不会被注意到

  9. 但是,如果 DLL 是动态链接的,则内存由单个共享版本的 malloc 分配,全局分配给以共享模式链接的所有代码。

  10. 此全局 malloc 分配的内存来自一个堆,该堆也是用于所有其他代码的堆,这些代码以动态 aka 共享模式链接,因此很常见。因此,来自该堆的任何泄漏都会成为影响整个过程的泄漏。

编辑 - 添加了链接场景的描述。

关于c++ - 卸载 DLL 时的内存泄漏是否会导致主机进程发生泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/132242/

相关文章:

c++ - 将 ppm 转换为 png

multithreading - CopyFileEx 可以从辅助线程调用吗?

.net - Ruby 可以导入 .NET dll 吗?

.net - 可以从 .net 调用的非常简单的 C++ DLL

c# - 如何找到使用的引用文件?

c++ - 在每次调用 : should I pass the engine, 分配或两者时生成不同数字的函数?

c++ - 运行时绑定(bind) C++

c# - 拦截来自其他程序的鼠标点击

c - 在 CreateProcess 中使用 STARTUPINFOEX

c++ - Fortran和C++混合编程: Fortran can not call C++ subroutines