在dll里malloc/new/cvCreate分配内存,在exe里free/Releases释放内存时会出错。

写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是:
其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL 中有 bug。

以下文字引用自 http://hi.baidu.com/huhe/blog/item/0b422edd1f1563d98c1029a3.html

一个模块一个堆,一个线程一个栈。

dll里malloc的内存,在exe里free会出错。

CRT(C运行时期库)不是使用进程缺省的堆来实现malloc(new中调用malloc)的,而是使用一个全局句柄HANDLE _crtheap来分配内存的。这个_crtheap是在XXXCRTStartUp(CRT提供的进口点函数)中创建的。  
由于CRT静态连接,则楼主的DLL里有也有一个CRT,因此也有一个_crtheap。而在dll中的new使用dll中的_crtheap句柄分配堆,在exe中的delete使用exe中的_crtheap释放堆,当然失败!

解决办法:
1。在DLL中输出一个函数给EXE调用,专门用来释放由DLL分配的内存;
2。用GlobalAlloc()代替new,用GlobalFree()代替delete;
3。使用单一的堆,分配内存使用HeapAlloc(GetProcessHeap(),0,size),释放内存使用HeapFree(GetProcessHeap(),0,p);
4。把dll和exe的Settings的C/C++选项卡的Code   Generation的Use   Run-time   liberary改成Debug   Multithreaded   DLL,在Release版本中改成Multithreaded   DLL;这样使用一个CRT了——MSVCRT.DLL。

所以得到的结论如下:
不管是使用malloc/free组合还是HeapAlloc/HeapFree组合,exe工程均需要设置成MultiThread DLL debug才能正常运行起来的,CSDN上的那个讨论在这儿貌似是由出入的,而且DLL的设置不能随意修改。所以若有涉及到这种问题的,最好的办法还是在哪个模块分配的就在哪个模块释放最好,要不然反倒会引来更多的麻烦。

时间: 2024-10-13 12:07:22

在dll里malloc/new/cvCreate分配内存,在exe里free/Releases释放内存时会出错。的相关文章

PHP如何释放内存之unset销毁变量并释放内存详解

PHP的unset()函数用来清除.销毁变量,不用的变量,我们可以用unset()将它销毁.但是某些时候,用unset()却无法达到销毁变量占用的内存!我们先看一个例子: <?php $s = str_repeat('1',255); //产生由255个1组成的字符串 $m = memory_get_usage(); //获取当前占用内存 unset($s); $mm = memory_get_usage(); //unset()后再查看当前占用内存 echo $m-$mm; ?> 最后输出u

【ios】收到系统内存警告时,应如何释放内存

- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; if (_userInfoViewCtl != nil && [_userInfoViewCtl isViewLoaded]) { if (_userInfoViewCtl.view.window == nil) { self.userInfoViewCtl = nil; } } } -(KEUserInfoViewController *) userInf

[转载]DLL和exe里的malloc和free不能混用的问题

源自: http://bjwf.cndev.org/2004/06/03/559/ http://bbs.csdn.net/topics/40214261 ====================================== 今天老玉米提了一个问题问为什么dll里malloc的内存如果在exe里free的话会出错,我分析了一下C库的原代码,得出结论如下: 刚看了一下malloc和free 的源代码,在这两个函数中都有对全局变量的引用,而malloc和free是C库函数,分别被静态链接到e

@清晰掉 malloc是如何分配内存的?

任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚至把malloc当做操作系统所提供的系统调用或C的关键字.实际上,malloc只是C的标准库中提供的一个普通函数,而且实现malloc的基本思想并不复杂,任何一个对C和操作系统有些许了解的程序员都可以很容易理解. 这篇文章通过实现一个简单的malloc来描述malloc背后的机制.当然与现有C的标准库

内存分配的几种方式,以及动态内存传递的注意事项

一.内存的分配方式?静态存储区,栈,堆 静态存储区:内存在程序编译的时候已经分配好,这块内存在程序的整个运行期间都存在,比如说全局变量. 栈:在栈上创建,在函数执行期间,函数内部局部变量和形参可以在栈上创建,函数执行这些存储单元自动释放.所以我们不能返回在函数内部定义的变量(函数定义的指针可以返回),因为他们在函数执行结束时已经被销毁了,处理器的指令集有关于站内部的分配运算,因此效率很高,但是分配的内存资源有限. 堆:从堆上分配,也称为动态内存分配,使用new malloc等申请任意多内存,程序

virsual studio 2008 跨dll释放内存,堆指针无效问题

运行时 触发了virsual studio的assert断点.输出内容如下: HEAP[xx.exe]: Invalid Address specified to RtlValidateHeap( 00C80000, 00CACFFC )Windows 已在 xx.exe 中触发一个断点. 其原因可能是堆被损坏,这说明 xx.exe 中或它所加载的任何 DLL 中有 Bug. 原因也可能是用户在 xx.exe 具有焦点时按下了 F12. 经过屏蔽最近的修改内容,逐渐找到原因是 传递的一个结构体中

频繁分配释放内存导致的性能问题的分析

频繁分配释放内存导致的性能问题的分析 现象 1 压力测试过程中,发现被测对象性能不够理想,具体表现为: 进程的系统态CPU消耗20,用户态CPU消耗10,系统idle大约70 2 用ps -o majflt,minflt -C program命令查看,发现majflt每秒增量为0,而minflt每秒增量大于10000. 初步分析 majflt代表major fault,中文名叫大错误,minflt代表minor fault,中文名叫小错误. 这两个数值表示一个进程自启动以来所发生的缺页中断的次数

[CareerCup] 13.9 Aligned Malloc and Free Function 写一对申请和释放内存函数

13.9 Write an aligned malloc and free function that supports allocating memory such that the memory address returned is divisible by a specific power of two. EXAMPLE align_malloc (1000,128) will return a memory address that is a multiple of 128 and t

详谈内存管理技术(二)、内存池

嗯,这篇讲可用的多线程内存池. 零.上期彩蛋:不要重载全局new 或许,是一次很不愉快的经历,所以在会有这么一个"认识".反正,大概就是:即使你足够聪明,也不要自作聪明:在这就是不要重载全局new,无论你有着怎样的目的和智商.因为: class XXX{ public: XXX* createInstance(); }; 这是一个不对称的接口:只告诉了我们如何创建一个[堆]对象,但是释放呢??! 很无奈,只能假设其使用全局默认的delete来删除(除此之外,没有其他选择):这时,我为了