最近在开发项目的时候被这个错误郁闷很久,本来以为是dll加载出错或者是分配内存出错。找了很久都没找出。在网上找了些方法,终于在下面的方法中解决了问题。
1、
这是运行库文件时的错误。
解决方案:打开项目属性-->配置属性-->C/C++-->代码生成-->运行时库,改成多线程调试DLL
编译运行,然后可能会出项如下错误:
fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD
解决方案:打开项目属性-->配置属性-->常规-->项目默认值-->MFC的使用,选择“在共享 DLL 中使用 MFC”,就OK了~
如果上面这些都没用,那么就不是库文件运行的错误了,你可以试一下“清理解决方案”,然后重新生成,没准就行了。这个好像没有什么道理,可能是Visual Studio的一个bug吧
如果还不可以可以尝试下面的方法
2
一个模块一个堆,一个线程一个栈。
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的设置不能随意修改。所以若有涉及到这种问题的,最好的办法还是在 哪个模块分配的就在哪个模块释放最好,要不然反倒会引来更多的麻烦。
from
http://blog.csdn.net/blz_wowar/archive/2008/03/13/2176536.aspx
上面这文章是我在找“...其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。”解决办法的时候找到的,学到一点,呵呵。可惜我那工程的直接原因并不是因为上面所说的(也许间接原因是),我的工程里是开启一个UI线程,UI 线程中有一个view,结果单步调试时报错“...其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。”,最后解决办法是,view需要用new创建,不能直接通过create来创建,原因是view应该是建在堆上
3 ]写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是: 其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL 中有 bug。 想了半天以为是自己的写法有问题,后终于在google上找 到了原因,汗。。。 以下文字引用自 http://hi.baidu.com/huhe/blog/item/0b422edd1f1563d98c1029a3.html 一个模块一个堆,一个线程一个栈。 CRT(C运行时期库)不是使用进程缺省的堆来实现malloc(new中调用malloc)的,而是使用一个全局 句柄 HANDLE _crtheap来分配内存的。这个_crtheap是在XXXCRTStartUp(CRT提供的进口点函数)中 创建的。 的_crtheap句柄分配 堆,在exe中的delete使用exe中的_crtheap释放堆,当然失败! 解决办法: (GetProcessHeap(),0,p); Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL;这样使用一个CRT了 ——MSVCRT.DLL。 以上是在网上找到的资料,今天做过详细测试,结果如下: MultiThread debug,所以不管怎么样,总是会抛异常. 这就间接证明了上述的描述是正确的, 若我修改exe工程 设置是 MultiThread DLL debug, 那么malloc/free组合就能很好的工作起来了。 中HeapFree(GetProcessHeap(), 0, p)释放,,则还是无法正常运行,还是抛异常。若exe中设置成MultiThread DLL debug就正常运行了。 正常运行起来的,CSDN上的那个讨论在这儿貌似是由出入的,而且DLL的设置不能随意修改。所以若有涉及到这种 问题的,最好的办法还是在 哪个模块分配的就在哪个模块释放最好,要不然反倒会引来更多的麻烦。 from http://blog.csdn.net/blz_wowar/archive/2008/03/13/2176536.aspx 上面这文章是我在找“...其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。 ”解决办法的时候找到的,学到一点,呵呵。可惜我那工程的直接原因并不是因为上面所说的(也许间接原因是), 我的工程里是开启一个UI线程,UI 线程中有一个view,结果单步调试时报错“...其原因可能是堆被损坏,这也说 明 **.exe 中或它所加载的任何 DLL 中有 bug。”,最后解决办法是,view需要用new创建,不能直接通过create 来创建,原因是view应该是建在堆上 |
==========
VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT)、多线程调试(/MTd)、多线 程DLL(/MD)、多线程调试DLL(/MDd)、单线程(/ML)、单线程调试(/MLd)。
其中以小写“d”结尾的选项表示的DEBUG版本的,没有“d”的为RELEASE版本。大型项目中必须要求所有组件 和第三方库的运行时库是统一的,否则将会出现LNK2005井喷。 单线程运行时库选项/ML和/MLd在VS2003以后就被废了。 /MT和/MTd表示采用多线程CRT库的静态lib版本。该选项会在编译时将运行时库以静态lib的形式完全嵌入。 该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因 链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的 内存管理有多份,最终将导致致命的“Invalid Address specified to RtlValidateHeap”问题。另外托管C++和 CLI中不再支持/MT和/MTd选项。 /MD和/MDd表示采用多线程CRT库的动态dll版本,会使应用程序使用运行时库特定版本的多线程DLL。链接时 将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的 VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。 因/MD和/MDd方式不会 将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一 个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。 结论:/MD和/MDd将是潮流所趋,/ML和/MLd方式请及时放弃,/MT和/MTd在非必要时最好也不要采用 了。
|
到此,我相信你的问题已经解决了^_^
已投稿到: |
排行榜
|
---|