DLL和exe里的malloc和free不能混用的问题
2010年12月26日
今天老玉米提了一个问题问为什么dll里malloc的内存如果在exe里free的话会出错,我分析了一下C库的原代码,得出结论如下:
刚看了一下malloc和free 的源代码,在这两个函数中都有对全局变量的引用,而malloc和free是C库函数,分别被静态链接到exe和dll里,这样他们引用的全局变量也会有两份各是各的,自然不能混用。
GlobalAlloc之类的windows API函数应该行。
茶壶贴了一贴,说dll因为有自已的堆栈所以不能混用,我表示怀疑,继续看源代码,找到支持上面结论的真正原因:
DLL是否有自已的堆栈我不知道, 但dll和exe里的malloc和free不能混用的真正原因就是我上面说的,有源代码为证,
malloc 里真正分配的是这一句,见malloc.c里
return HeapAlloc( _crtheap, 0, size );
_crtheap是个全局变量,在_heap_init这个函数里初始化,见heapinit.c:
// Initialize the "big-block" heap first.
if ( (_crtheap = HeapCreate( mtflag ? 0 : HEAP_NO_SERIALIZE, BYTES_PER_PAGE, 0 )) == NULL )
return 0;
而_heap_init 在wWinMainCRTStartup 这个函数里调用(见crt0.c),同时也会在_DllMainCRTStartup里调用(见dllcrt0.c )。而winmain和dllmain 分别在wWinMainCRTStartup 和DllMainCRTStartup里调用,但都在调用了_heap_init之后(事实上是DllMainCRTStartup调用了_CRT_INIT之后才会调用用户的dllmain,而_CRT_INIT里调用了_heap_init这也就是说至少_crtheap这个变量在dll和exe里会各有一份,这才是dll和exe里不能混用malloc和free的真正原因。
如果使用LoadLibraryEx装入dll,并指定DONT_RESOLVE_DLL_REFERENCES参数来让系统不调用用户的dllmain,dll和exe的malloc和free仍然不能混用,因为即使指定了DONT_RESOLVE_DLL_REFERENCES参数DllMainCRTStartup里仍会调用_CRT_INIT来初始化自已的_crtheap。
[补充]
DLL中的内存分两类,一类是共享内存,一类是进程私有内存
例如,进程P1和P2同时引用同一个DLL,一般情况下,DLL中声明的变量会在P1和P2的进程空间内产生各自的副本
也就是说,DLL中的变量,对于各个进程是独立的
某些情况下,有必要在DLL中产生一块共享内存,多个进程都访问到同一块数据,比如,某些设备驱动程序,需要内部保留一个设备忙/空闲之类的状态标志,这个标志就必须作为共享内存存在,保证只有一份
对于DLL中分配的内存,我觉得本身没有什么神秘之处,Windows程序之下的内存分配,最终都需要通过OS来完成,老玉米的问题,很可能是象北京色狼说的那样,不是内存本身的问题,是内存管理程序的故障
因为各种语言的RTL库中的内存管理程序,它本身也需要通过自己的内部数据来管理内存分配的状态
在DLL中调用的内存管理程序和在EXE中调用的内存管理程序不是同一块,而且它们内部维护内存分配信息的数据也不是同一块,所以造成老玉米的问题
如果上面的说法成立的话,那么,不要用C的RTL来申请和释放内存,直接通过Windows API来申请和释放内存,比如GlobalAlloc/GlobalFree/LocalAlloc/LocalFree/HeapAl loc/HeapFree等等,应该就不会有问题了
老玉米快去测试,报告结果
当然如果dll和exe的编写语言不同的话,更不能混用了,各种语言都会封装winAPI来实现自已的内存管理库函数。
原文地址: http://bjwf.cndev.org/2004/06/03/559/
发表评论
-
VS2005和Eclipse中调试JNI的方法
2012-01-20 12:21 1385VS2005和Eclipse中调试JNI的 ... -
Samba PDC 服务器安装笔记
2012-01-20 12:21 828Samba PDC 服务器安装笔记 ... -
RMI OS
2012-01-20 12:21 883RMI OS 2010年12月15日 过去的4年(或者六 ... -
基于mainloop io_event 的signal机制
2012-01-20 12:21 817基于mainloop io_event 的sign ... -
编程学习的七大攻略
2012-01-19 17:02 715编程学习的七大攻略 20 ... -
Symbian 3系统的弟弟妹妹们。哥哥教你编写一个简单实用的小软件――python编程
2012-01-19 17:02 803Symbian 3系统的弟弟妹妹们。哥哥教你编写一个简单实用的 ... -
教大家认识PY平台
2012-01-19 17:01 1097教大家认识PY平台 2011 ... -
【Python】一、编写代码
2012-01-19 17:01 691【Python】一、编写代码 ... -
Harmattan Python for MeeGo 1.2 发布
2012-01-19 17:01 621Harmattan Python for MeeGo 1.2 ... -
史上嫁不出去的公主都有谁
2012-01-17 06:46 737史上嫁不出去的公主都有谁 2010年10月23日 ... -
唐朝义成公主的悲惨命运是怎样的?
2012-01-17 06:46 691唐朝义成公主的悲惨命运是怎样的? 2011年05月13日 ... -
Rundll32.exe文件详解
2012-01-17 06:46 737Rundll32.exe文件详解 2010年07月16日 ... -
Rundll32.exe使用方法大全
2012-01-17 06:46 539Rundll32.exe使用方法大全 ... -
程序如何关联后缀为mte的文件
2012-01-17 06:46 705程序如何关联后缀为mte ... -
2011年第十届中国机械(越南)展览会
2012-01-16 05:37 5262011年第十届中国机械(越南)展览会 2010年11月22 ... -
2010年第八届中国机械(越南)展览会
2012-01-16 05:36 6152010年第八届中国机械(越南)展览会 2009年11月05 ... -
越南新娘
2012-01-16 05:36 27越南新娘 2009年10月08日 越南新娘网的宣传资料及 ...
相关推荐
浅谈C中的malloc和free
用C自己实现malloc和free,需要的可以看下,没实际用处,不过可以了解C的原型原理
在VC2008上实现malloc和free,内含注释以及图形解释
定义了一个10M大小的数组,每次分配空间都从这10M中分配,原理是分配的时候空间足够...模拟动态内存分配,模拟malloc和free。 自己的作业,当然也有很多欠缺的地方,比如没有考虑多线程同时调用这类的问题。仅供参考。
自己实现的malloc 和 free 用的双向链表 尽量做了注释
malloc_free.exe
由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的 任务强加于malloc /free. 3 ,因此C++ 语言需要一个能完成动态内存分配和初始化工作的运算符new ,以一个能完成...
C语言的malloc和free函数.pdf
实现自己的mem_malloc和mem_free
详细介绍了c语言中malloc()和free()的基本用法、概念和机制
详述了内存管理中malloc和free的用法
主要介绍了C语言基础之malloc和free函数详解的相关资料,需要的朋友可以参考下
malloc和calloc区别 函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别。 malloc()函数有一个参数,即要分配的内存空间的大小: void *malloc(size_t size); calloc()函数有两个参数,分别为元素...
C语言中内存的管理主要是依据malloc和free实现的,其中malloc主要是实现内存的分配,而free则是实现内存的释放。虽然这是我们已经很熟悉的,但是还是存在一些问题。特别是当结构体中存在指针的情况下,各种问题也就...
malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数malloc函数...
Malloc和mfree函数的实现原理,可参考
my_malloc:自己动手写的malloc函数.希望对大家了解内存管理有所帮助
Malloc()与free()是C++/C语言的标准库函数,new/delete是C++的运算符,它们都可用于申请和释放动态内存。
本文叙述了calloc和malloc用法的区别,函数malloc()和函数calloc()的主要区别是前者不能初始化所分配的内存空间,而后者能。