DLL函数中内存分配及释放的问题
DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了。主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的
情况,这里总结一下,做为资料。 错误现象是“其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug”
我的现象还有一个,就是直接运行EXE不在程序里调试,不会报这个错误。 从网上找到的资料是: 一个模块一个堆,一个线程一个栈。 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。 以下是CSDN上的讨论,同样讨论的很详细了
以上是在网上找到的资料,今天做过详细测试,结果如下:
测试1:使用malloc/free组合来分配和释放内存,DLL中使用malloc分配,exe中使用free释放。 我建的是Win32 DLL工程, C/C++->Code generation 设置是 Multithread DLL debug, 但是exe工程设置是MultiThread debug,所以不管怎么样
,总是会抛异常. 这就间接证明了上述的描述是正确的, 若我修改exe工程设置是 MultiThread DLL debug, 那么malloc/free组合就能很好的工
作起来了。
测试2:使用HeapAlloc/HeapFree组合来分配和释放内存,DLL中使用HeapAlloc分配,exe中释放。 exe的配置还是MultiThread Debug,DLL中HeapAlloc(GetProcessheap(), HEAP_ZERO_MEMORY, 1024)分配,exe中HeapFree(GetProcessHeap(),
0, p)释放,,则还是无法正常运行,还是抛异常。若exe中设置成MultiThread DLL debug就正常运行了。
测试3:还是使用HeapAlloc/HeapFree来进行,但是DLL中导出一个方法来释放DLL中分配的内存。 若exe配置是MultiThread Debug,无法正常运行,抛异常。若修改成MultiThread DLL debug正常运行。 所以得到的结论如下: 不管是使用malloc/free组合还是HeapAlloc/HeapFree组合,exe工程均需要设置成MultiThread DLL debug才能正常运行起来的,CSDN上的那个
讨论在这儿貌似是由出入的,而且DLL的设置不能随意修改。所以若有涉及到这种问题的,最好的办法还是在哪个模块分配的就在哪个模块释放
最好,要不然反倒会引来更多的麻烦。
我在找“...其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。”解决办法的时候找到的,学到一点,呵呵。可
惜我那工程的直接原因并不是因为上面所说的(也许间接原因是),我的工程里是开启一个UI线程,UI线程中有一个view,结果单步调试时报错
“...其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。”,最后解决办法是,view需要用new创建,不能直接通
过create来创建,原因是view应该是建在堆上
以上是在网络上搜到的资料。我的实际情况又与这个有所不同,当然,我已经按照上述的方法都测试过了,没有解决问题。 我的问题是在线程里分配了(NEW)一个类的指针(一个包含套接字的类),但在程序退出时报这个错误。后来经过考虑,我发现可能是在程序
退出时,子线程仍在运行,造成指针仍在使用,所以我在退出时把子线程的循环条件置FALSE后,解决。 随即又出现一个问题,我在程序退出时DELETE保存在LIST里的SOCKET的时仍然报这个错误。最后解决办法仍是上面的思路,(多线程)把程序
关闭时,先shutdown套接字,然后closesocket套接字,最后延时2秒,OK,取代了原来::WaitForSingleObject(hRecv,2000)然后再
TerminateThread(hRecv,temID);比较暴力的方法。
DLL函数中内存分配及释放的问题的更多相关文章
- C语言中内存分配 (转)
在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...
- 【转】C语言中内存分配
原文:C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要 ...
- C语言中内存分配
C语言中内存分配 在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要 ...
- C++学习011-常用内存分配及释放函数
C++用有多种方法来分配及释放内存,下面是一些经常使用的内存分配及释放函数 现在我还是一个技术小白,一般用到也指示 new+delete 和 malloc和free 其他的也是在学习中看到,下面的文字 ...
- C语言中的内存分配与释放
C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...
- (转)C++ STL中的vector的内存分配与释放
C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...
- Com组件的内存分配和释放,CredentialProvider SHStrDup 字符串拷贝问题
一.简单介绍 熟悉CredentialProvider的同学应该知道,他为一个Com组件,于是,在这里的内存分配(字符串拷贝)的一系列操作就要依照con的标准来. 二.Com组件的内存分配和释放 CO ...
- java中内存分配策略及堆和栈的比较
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
- 内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料 ...
随机推荐
- yum安装mariadb
安装mysql yum install mariadb mariadb-server MySQL-python mysql-devel Package MySQL-python-1.2.5-1.ibm ...
- JavaScript Patterns 3.2 Custom Constructor Functions
When you invoke the constructor function with new, the following happens inside the function: • An e ...
- Force.com平台基础
当我开始写这篇博客的时候,<Force.com Platform Fundamentals>的PDF版本我还没看到十分之一.由于PDF全部是英文的,所以我看起来比较吃力.我尝试过边看边做笔 ...
- MongoDB学习笔记——聚合操作之MapReduce
MapReduce MongoDB中的MapReduce相当于关系数据库中的group by.使用MapReduce要实现两个函数Map和Reduce函数.Map函数调用emit(key,value) ...
- mysql主从同步问题解决汇总
出现问题原因:出现这个问题的原因是之前曾做过主从复制!问题:ERROR 1201 (HY000): Could not initialize master info structure; more e ...
- volatile与synchronized关键字
volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...
- Golang tips ----- 函数
1.在函数调用时,Golang没有默认参数值 2.一个函数声明如果没有函数体,表面该函数不是由Golang实现的,这样的声明定义了函数标识符 3.拥有函数名的函数只能在包级语法块中被声明 4.函数值( ...
- 二叉树结构 codevs 1029 遍历问题
codevs 1029 遍历问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 我们都很熟悉二叉树的前序.中序.后序遍 ...
- 改造二叉树 (长乐一中模拟赛day2T1)
1.改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随 ...
- 在WPF控件上添加Windows窗口式调整大小行为
起因 项目上需要对Canvas中的控件添加调整大小功能,即能在控件的四个角和四条边上可进行相应的拖动,类似Windows窗口那种.于是在参考以前同事写的代码基础上,完成了该功能. 代码实现 Adorn ...