Dll分配的内存块,应用释放的问题

简介:

写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是:
其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL 中有 bug。
想了半天以为是自己的写法有问题,后终于在google上找到了原因,汗。。。

以下文字引用自 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。
 
以下是CSDN上的讨论,同样讨论的很详细了
http://topic.csdn.net/t/20031009/17/2338051.html 

以上是在网上找到的资料,今天做过详细测试,结果如下:

测试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的设置不能随意修改。所以若有涉及到这种问题的,最好的办法还是在哪个模块分配的就在哪个模块释放最好,要不然反倒会引来更多的麻烦。

目录
相关文章
|
11天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
1月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
65 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
49 2
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
运维 JavaScript Linux
容器内的Nodejs应用如何获取宿主机的基础信息-系统、内存、cpu、启动时间,以及一个df -h的坑
本文介绍了如何在Docker容器内的Node.js应用中获取宿主机的基础信息,包括系统信息、内存使用情况、磁盘空间和启动时间等。核心思路是将宿主机的根目录挂载到容器,但需注意权限和安全问题。文章还提到了使用`df -P`替代`df -h`以获得一致性输出,避免解析错误。
|
3月前
|
数据采集 Rust 安全
Rust在网络爬虫中的应用与实践:探索内存安全与并发处理的奥秘
【8月更文挑战第31天】网络爬虫是自动化程序,用于从互联网抓取数据。随着互联网的发展,构建高效、安全的爬虫成为热点。Rust语言凭借内存安全和高性能特点,在此领域展现出巨大潜力。本文探讨Rust如何通过所有权、借用及生命周期机制保障内存安全;利用`async/await`模型和`tokio`运行时处理并发请求;借助WebAssembly技术处理动态内容;并使用`reqwest`和`js-sys`库解析CSS和JavaScript,确保代码的安全性和可维护性。未来,Rust将在网络爬虫领域扮演更重要角色。
80 1
|
3月前
|
JavaScript 前端开发 Java
JavaScript内存泄露大揭秘!你的应用为何频频“爆内存”?点击解锁救星秘籍!
【8月更文挑战第23天】在Web前端开发中,JavaScript是构建动态网页的关键技术。然而,随着应用复杂度增加,内存管理变得至关重要。本文探讨了JavaScript中常见的内存泄露原因,包括意外的全局变量、不当使用的闭包、未清除的定时器、未清理的DOM元素引用及第三方库引发的内存泄露。通过了解这些问题并采取相应措施,开发者可以有效避免内存泄露,提高应用性能。
55 1
|
2月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
71 0