日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

小心DLL链接静态库时的内存错误

發布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 小心DLL链接静态库时的内存错误 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近寫的模塊,在獨立的應用程序中測試是沒問題的,但把它裝配成DLL后,再在另一個應用程序中調用時卻出現了內存錯誤。程序的模塊鏈接關系大概是這樣的:

module就是我所寫的模塊,在這里被封裝為DLL,因為要使用json相關的功能,該DLL鏈接了一個靜態庫 (jsoncpp.lib)。最后在應用程序中導入并使用module.dll,同時因為在應用程序中也需要用到json,所以應用程序也鏈接了jsoncpp.lib。

以下用一些偽代碼來描述這些模塊間的調用關系,以具現出這個錯誤。

jsoncpp.lib為c++提供了功能齊全的json操作,其核心的類是Json::Value。(閱讀本篇文章你無需了解太多json)

module.dll中導出了一個接口:

//ModuleClass.h #include "json/value.h"#if defined MODULE_EXPORTS #define MODULE_EXPORTS __declspec(dllexport) #else #define MODULE_EXPORTS __declspec(dllimport) #endifclass ModuleClass { public:MODULE_EXPORTS void AllocSomeMemory( Json::Value &root ){// 這將申請一些內存,因為會new出一個Json::Value,并append到root上root.append( "testString" );} };

應用程序:

1#include "json/value.h"
2#include "ModuleClass.h"
3int?main()
4{
5????Json::Value root;
6????ModuleClass::AllocSomeMemory( root );
7}

在Debug模式下,當main函數執行完畢,對Json::Value root進行析構時,程序便出現了異常。分析下,很顯然,調用ModuleClass::MallocMemoryHere時申請的內存,是在module.dll中申請的,而對這些內存的析構則是在應用程序(.exe)中進行的(析構root會同時析構append在root上的所有子Json::Value)。不過,這是異常的真正原因么?

追蹤到異常的出錯點:dbgheap.c文件中那句ASSERT語句。

1/*
2* If this ASSERT fails, a bad pointer has been passed in. It may be
3* totally bogus, or it may have been allocated from another heap.
4* The pointer MUST come from the 'local' heap.
5*/
6_ASSERTE(_CrtIsValidHeapPointer(pUserData));

注釋中的最后一句話”The pointer MUST?

come from the ‘local’ heap“引起了我的警惕,難道對于內存的申請和釋放不是在同一個heap上,除了‘local’ heap還有一個什么heap么。

去MSDN上搜索了關于_CrtIsValidHeapPointer,似乎找到了答案,以下這段話是MSDN上對于_CrtIsValidHeapPointer的介紹:

The _CrtIsValidHeapPointer function is used to ensure that a specific memory address is within the local heap. The local heap refers to the heap created and managed by a particular instance of the C run-time library.?If a dynamic-link library (DLL) contains a static link to the run-time library, it has its own instance of the run-time heap, and therefore its own heap, independent of the application’s local heap.?When _DEBUG is not defined, calls to _CrtIsValidHeapPointer are removed during preprocessing.

注意字體加粗的部分,這不正應對我的情形么?!錯誤不在于DLL中申請的內存在EXE中釋放,而在于如果這個DLL擁有一個靜態鏈接,它就會擁有獨立的運行時堆,獨立于應用程序的堆。這樣對于內存申請和釋放并不是在同一個堆上進行的,當然出錯了。

解決:雖然MSDN上最后說,如果把項目改成release的,這個ASSERT就將避免,但這是放縱內存泄露,最好的解決辦法是將靜態鏈接也改成動態鏈接,這樣就使得DLL能夠和應用程序共享同一個堆,錯誤也得以避免。

于是,我修改了jsoncpp的項目配置,生成jsoncpp的動態鏈接庫,而不是使用靜態庫,重新導入到module.dll中,錯誤解決。



總結

以上是生活随笔為你收集整理的小心DLL链接静态库时的内存错误的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。