C Vector的使用誤區

2021-06-23 01:57:00 字數 1082 閱讀 3437

初始化vector並傳引用到dll中,dll中為該引用新增節點,vector記憶體釋放時會報堆疊錯誤,原因?

這個問題其實挺好避免的,說白了就是不要乙個模組new,另乙個模組delete,不要認為你的vector的節點資料在棧上,vector的本質就是乙個變長陣列,怎麼會在棧上呢,資料肯定是在堆上的,這樣你就是在dll中申請的儲存,在主程式裡面釋放的儲存,出錯很正常。

原因簡要的分析一下:

1:像你說的一樣,和runtime library的設定有關係,如果你設定為靜態鏈結的方式,那麼每乙個模組都會有乙個crt堆,crt堆是在可執行模組的入口點分配的@記憶體檢測模組的實現中dll模組本身的堆空間建立方式類似,crt堆和程序預設的堆空間是不交叉的,但是在乙個線性的位址空間,在訪問不同的模組資料時候,通過位址偏移可以很方便的進行訪問。

2:如果你採用靜態鏈結的方式,每乙個可執行模組都會建立自己的crt堆,在模組內部進行new和delete操作的時候,都是在crt堆上進行的,這樣不會出錯,可是你的vector的push操作是在dll內部,這時候很有可能已經發生了一次記憶體申請操作(可能vector的空間不足以儲存新資料,所以進行新的儲存申請,將舊資料進行一次拷貝,這時候申請的儲存是在dll模組的crt堆上,而不是在程序預設堆上),vector的記憶體釋放操作卻是在dll外部,形成這種情況: 在dll的crt堆上申請的空間,卻在主程式內部釋放空間,即使使用的new和delete是契合的,也有可能出問題。

3:解決方案,修改鏈結方式為動態連線,也就是dll crt的方式,這種方式下crt堆只會建立乙份,也就是主可行性模組載入的時候建立的那乙份,在同乙個模組申請釋放儲存自然不會出錯。

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

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

C vector的使用操作

vector 底層結構 動態順序表 vector的使用 includeusing namespace std int main vectorv4 array,array sizeof array sizeof array 0 vectorv5 v4 for size t i 0 i v2.size ...

C vector函式的使用

以下為vector的用法 摘錄 vector 是c stl的乙個重要成員,使用它時需要包含標頭檔案 include 一 vector 的初始化 可以有五種方式,舉例說明如下 1 vector int a 10 定義了10個整型元素的向量 尖括號中為元素型別名,它可以是任何合法的資料型別 但沒有給出初...

C vector的使用總結

一 c vector類為內建陣列提供了一種替代表示,與string類一樣 vector 類是隨標準 c 引入的標準庫的一部分,使用時需包含標頭檔案 include 二 c vector類有兩種使用方式 第一種 stl方式 vector string text 1.我們向 vector 中插入元素,而...