1. 程式人生 > >Dll中運用vector的堆疊崩潰

Dll中運用vector的堆疊崩潰

今天在除錯程式的時候遇到了這個問題。

先給出出問題的程式碼:

[.dll]
vector<string> getPerList(){return _perList;}
vector<string> getGrpList(){return _grpList;}
呼叫該dll的程式碼:
[CContactDialog.cpp]
	list.requestPerList(p_contact->_id);
	list.requestGrpList(p_contact->_id);

	p_contact->_priv_list=list.getPerList();
	p_contact->_grp_list=list.getGrpList();

其中_priv_list,_grp_list都是CContactDialog的vector<string>型別的成員變數。


出錯提示:


在網上搜了下問題:

簡單的講把vector傳入到dll中後,新增節點時,在dll中會進行一些記憶體分配,當vector析構時,由於申請和釋放不是相同模組,這會導致vector不知道如何正確釋放dll中分配的記憶體。

還有一個問題更嚴重一些,一般比較隱蔽。比如標準C++庫中的大多數類都直接或間接使用靜態資料。由於這些類通過模板例項生成的,每個映像包含一個給定的類的靜態資料成員的副本。當你在dll中使用或更改靜態資料成員時,(由於該靜態成員的程式碼駐留在可執行映像中,比如EXE),會造成可執行模組中的靜態資料成員不同步,這個動作可能會導致引發訪問衝突或資料出現丟失和其它不可預知的結果。

解決:

把生成dll的程式碼修改如下

[.dll]
const vector<string>& getPerList(){return _perList;}
const vector<string>& getGrpList(){return _grpList;}

我的理解是:

vector<string>作為返回值的時候,在dll中為臨時物件分配記憶體,被呼叫dll的程式碼中超出該臨時物件的作用域範圍時,臨時物件將被銷燬,帶正如上面說的一樣,記憶體是在dll中分配的,卻在呼叫dll的程式碼中釋放,所以出現了錯誤。改成const vector<string>&後,dll中將不會產生臨時物件,就不會出想這個問題。