Windows 下主程序与动态库(*.dll)释放对方分配的内存操作要点
同样的代码程序:主程序中释放了一块在 动态库(*.dll)或共享库(*.so) 中分配的内存,Windows 将会出现程序崩溃,而 Linux 则正常运行。在 linux 下,每个进程只有一个 heap ,在任何一个共享库模块 *.so 中通过 new 或者 malloc 来分配内存的时候都是从这个唯一的 heap 中分配的,那么自然你在其它什么
·
同样的代码程序:
主程序中释放了一块在 动态库(*.dll)或共享库(*.so) 中分配的内存,
Windows 将会出现程序崩溃,而 Linux 则正常运行。
在 linux 下,每个进程只有一个 heap ,
在任何一个共享库模块 *.so 中通过 new 或者 malloc 来分配内存的时候都是从这个唯一的 heap 中分配的,
那么自然你在其它什么地方都可以释放。
但是 windows 下面确不是如此:
1. windows 允许一个进程中有多个 heap ,那么这样就需要指明一块内存要在哪个 heap 上分配,
2. 这样的设计显然是比较灵活的,
3. 如果一个进程需要动态库支持,系统在加载 dll 的时候,在 dll 的启动代码 _DllMainCRTStartup 中,
4. 从上面的分析中可以看出,对于 crt 来说,由于每个 dll 都有自己的 heap ,
事情基本清楚了,在 windows 下一个进程存在着多个 heap ,
除了一个主 heap 外,还有很多的 __crtheap ,用来处理通过 C/C++ 的运行库进行的内存操作。
所以使用 new/malloc 来分配的内存实际上都是局部的,可以在多个 dll 中共享,
但是却必须是谁申请谁释放。
这个是 Windows 下的一个规则。以前知道这个规则,但是不知道为什么,现在算是比较明白了。
如果在 dll 内部使用 HeapAlloc(GetProcessHeap(), 0, 字节块大小 ) 来分配的内存,
是可以在 dll 以外释放的,
因为这时内存分配在全局的主 heap 上,而不是分配在 dll 自己的 __crtheap 上。
转自 http://blog.sina.com.cn/s/blog_4c451e0e0100u9gu.html
更多推荐
已为社区贡献4条内容
所有评论(0)