天天看點

_CrtIsValidHeapPointer 跨dll接口參數資料傳遞問題

這種問題,在編譯的時候是不會出現問題的,但是在運作時就會崩潰,

例如 接口 來至A.dll

#define MAX_LINE 255

struct _ttt

{

_ttt()

{

memset(a,0,MAX_LINE*sizeof(TCHAR));

memset(b,0,MAX_LINE*sizeof(TCHAR));

memset(c,0,MAX_LINE*sizeof(TCHAR));

}

TCHAR a[MAX_LINE];

TCHAR b[MAX_LINE];

TCHAR c[MAX_LINE];

};

typedef CArray<_ttt,_ttt&> CArrayTTT;

extern __declspec(dllexport) void Fun(LPCTSTR pszFilePath, CArrayTTT& arr);

(這裡的pszFilePath 是一個檔案路徑,這個沒什麼問題,arr是傳入在傳出的參數,就是在接口裡面會有資料往裡面添加)

在另外一個exe工程裡調用 A.dll 中的接口Fun

{

CArrayTTT arr;

CString sFilePath = _T("a.txt");

Fun(sFilePath,arr);

}

到這裡應該編譯連接配接都沒問題,但是在運作到這段代碼的時候,出了右邊的大括号就會崩潰,提示在_CrtIsValidHeapPointer函數裡異常,

這說明什麼:說明在釋放局部變量記憶體的時候出現了問題,查找相關資料得知(例如MSDN),dll中的資料堆棧是獨立的,跟目前應用程式是分開的,在目前應用程式中釋放dll中的堆棧空間是不對的,原因就是你把dll堆棧空間中的位址當成目前應用程式中的堆棧空間中的位址了,這段話說的我也是醉了,慢慢了解吧,反正這樣是不允許的。

如何解決這種問題呢,如果把dll和調用dll的堆棧空間區分開來處理,就不會出現這種問題了,就上面的例子 把 接口改下:我這裡這樣改的(也可以有其他更好的方法來處理)

extern __declspec(dllexport) void Fun(LPCTSTR pszFilePath, CArrayTTT*& pArr);

參數 pArr 的記憶體在dll中申請 

void Fun(LPCTSTR pszFIlePath, CArrayTTT*& pArr)

{

.....

pArr = new CArrayTTT();

....

}

當然 申請了記憶體就别忘了釋放

extern __declspec(dllexport) void ReleaseMem( CArrayTTT* pArr);

void ReleaseMem(CArrayTTT* pArr)

{

if(pArr != NULL)

{

delete pArr;

pArr = NULL;

}

}

在調用 Fun接口的應用程式中就得這樣來用了:

{

CArrayTTT* pArr;

CString sFilePath = _T("a.txt");

Fun(sFilePath,pArr);

ReleaseMem(pArr);

}

當然你也可以有其他的方法解決這種問題,隻要思想是對的,問題總能通過不同的方法來處理掉。

繼續閱讀