关于Cross-Dll问题(在不同的模块之间申请和释放内存)
来源:互联网 发布:屏蔽软件弹出广告 编辑:程序博客网 时间:2024/06/09 23:29
所谓Cross_Dll问题,就是在一个dll中申请了一段内存空间,在外部程序调用完该dll提供的功能后,为了不造成内存泄露,要释放掉在dll内部申请的空间。但是这种操作会引起程序崩溃。如下面的示例程序所示:
#ifndef DLL_NEW_H_#define DLL_NEW_H_#ifndef _DLL_NEW_DLL_#define DLL_NEW_API __declspec(dllimport)#else#define DLL_NEW_API __declspec(dllexport)#endifDLL_NEW_API void new_test(int * &p); #endif
#include "dll_new.h"void new_test(int * &p){p=new int;*p=12;}
以上为dll的源码,起名为dll_new.dll
下面是调用该dll的程序:
#include "dll_new.h"#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>#include <stdio.h>#pragma comment(lib,"dll_new.lib") //在dll中new出来的空间要在dll内部delete掉,如果在调用dll的外部程序中释放的话,会崩溃void main(){ /***********用于检测内存泄露**************/ //此代码检测不出dll里面的内存泄露!!! int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); tmpFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag( tmpFlag ); /*************用于检测内存泄露********************/ int *p=NULL; new_test(p); printf("%d\n",*p); delete p;}
如上述程序所示:指针p在dll的函数new_test中申请了空间,但是在外面程序delete的时候,会引起程序崩溃。
原因分析:
模块之间分配和释放内存有一些不安全因素,因为不同模块(特别是不同语言开发的模块)可能使用了不同的内存管理机制,这种情况是不是跨模块释放的,所以VC的Debug版中对内存释放做了检查,如果发现不是本模块分配的就会报错。
造成失败的原因是分配和释放内存不是由相同的堆管理程序完成的,例如动态链接库中的堆在默认情况下是由msvcrt.dll中的堆管理程序管理的 (以动态链接的方式),而exe程序的堆在默认情况下是由程序自己的代码管理(以静态链接的方式),由于它们的堆管理程序不同,当动态链接库分配的内存在 exe程序中释放时就会出错,因为exe程序所在的堆并没有分配这块内存,而你却要求它释放这块内存。
解决方法(三种解决办法):
1、将程序中所有的模块都链接到C/C++运行期库Multithreaded DLL,修改后所有分配和释放堆上内存的操作都由同一个堆管理程序管理,这样便解决了问题。
2、 在DLL中增加一个导出函数来释放内存。谁负责分配,谁就必须负责释放!
3、使用智能指针,如std::shared_ptr。这样不用自己释放内存,智能指针在发现引用计数为1的时候,会自动释放内存。
- 关于Cross-Dll问题(在不同的模块之间申请和释放内存)
- 关于在dll中申请内存,外部释放的问题
- 关于在dll中申请内存,外部释放的问题
- 关于在dll中申请内存,外部释放的问题
- 关于在dll中申请内存,外部释放的问题
- 关于QT的内存申请和释放
- 关于动态内存的申请和释放
- 关于QT的内存申请和释放
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- /MT、/MD编译选项,以及可能引起在不同堆中申请、释放内存的问题
- UVA10881:
- 开源中国iOS客户端学习——(十三)使用UIWebView控件布局视图
- PeekMessage & GetMessage 区别
- UVA 10591 - Happy Number
- [WIKIOI1281] Xn数列
- 关于Cross-Dll问题(在不同的模块之间申请和释放内存)
- Copy .vdi file by changing UUID in VirtualBox
- hdu 2066 一个人的旅行
- C#事件与代理的简单运用
- Git详解之四 服务器上的Git
- arm寄存器
- uva557 - Burger(汉堡)
- Combinations
- Eric Steven Raymond,How To Become A Hacker