STL容器vector的記憶體問題

2021-06-19 17:22:02 字數 1645 閱讀 1079

在stl的容器中,vector可以說是最容易理解和使用的容器了,以前使用陣列的時候,如果不確定有多少資料要儲存,就會預先分配乙個大的陣列,如果實際沒有用到那麼多,又會浪費很多的記憶體資源,如果不分配大的陣列又擔心不夠用,有了vector之後,這些問題再也不用擔心了,vector會動態的增長空間,當vector空間不足時會自動申請一片更大的記憶體空間,以儲存新的資料。

vector動態記憶體增長的過程如下:

1) 申請一塊更大的記憶體空間以儲存新資料。

2) 將資料從舊記憶體空間拷貝到新記憶體空間。

3) 析構舊記憶體空間中的物件。

4) 釋放舊記憶體空間。

對於程式設計師來說,這簡直就是乙個神器,但是在享受vector帶來方便的同時,它也隱藏了一些記憶體方面的問題,需要我們注意一下。

1、預先分配兩倍的記憶體空間

對於乙個陣列,只要通過元素的個數以及元素的型別就可以得到占用的記憶體空間,而對於vector情況就不一樣,為了提高效率,vector會預先分配一定的記憶體空間,減少申請記憶體以及資料移動的開銷,因此vector實際占用的記憶體空間要比需要的多一些。

如果對記憶體要求比較高的程式,使用vector一定要小心了,當vector空間不足時,會申請一塊約是當前占用記憶體兩倍的新空間以儲存更多的資料,若可用記憶體為1g,而當前vector已占用的記憶體空間0.5g,當再插入乙個元素,vector將會申請一塊約1g的記憶體空間,瞬間記憶體就被用光了,導致程式崩潰。

2、迭代器失效

當vector空間不足時,會申請一塊更大的記憶體空間,並將原指向記憶體空間的資料移動到新的記憶體空間中,接著,舊的記憶體空間將會被**。這裡就可能會出現問題了,當vector指向新的記憶體空間之後,原來指向舊記憶體空間的迭代器都會失效了,若再使用這些失效迭代器,將會出現coredump。因為當需要插入資料到vector的時候,就需要注意當前的迭代器還是否有效了。

3、釋放vector所佔記憶體

vector已經申請的記憶體空間並不會縮減,即使呼叫clear()函式,也只是清空vector的所有元素,真正占用的記憶體空間也不會減少。有一種方法可以釋放vector占用的記憶體空間,swap()函式可以交換兩個vector物件所指向的記憶體空間,

下面例子說明了swap()函式的使用方法,假設擁有乙個vector物件vec:

vectortmp;	//tmp為空

vec.swap(tmp); //vec和tmp交換指向的記憶體空間

如果**想要更加精簡,則可以選擇下面的寫法:

vec.swap(vector());//vec與臨時物件交換了指向的記憶體空間
上面兩種方式都使用乙個沒有資料的vector物件與當前vetor物件進行了交換,對於vec來講,其記憶體空間縮減為0,同理,若想vec變為指定大小,則只需要與乙個大小一樣的vector物件進行swap即可。

4、預先申請記憶體空間

若一開始就大概確定需要的記憶體空間,則可以使用vector的reserve()函式預先申請足夠的記憶體空間,這樣做,既可以減少記憶體增長時的申請記憶體和資料移動的開銷,避免了迭代器失效的問題,也防止了申請了超出預期的的記憶體空間,導致記憶體耗盡的問題;若一開始不確定需要的記憶體空間,則可以先預留足夠大的空間,當所有資料都插入後,通過swap()函式去除多餘的容量即可。

STL容器vector的記憶體問題

在stl的容器中,vector可以說是最容易理解和使用的容器了,以前使用陣列的時候,如果不確定有多少資料要儲存,就會預先分配乙個大的陣列,如果實際沒有用到那麼多,又會浪費很多的記憶體資源,如果不分配大的陣列又擔心不夠用,有了vector之後,這些問題再也不用擔心了,vector會動態的增長空間,當v...

STL順序容器 vector

vector是乙個線性順序結構。相當於陣列,但其大小可以不預先指定,並且自動擴 展。它可以像陣列一樣被操作,由於它的特性我們完全可以將vector 看作動態數 組。在建立乙個vector 後,它會自動在記憶體中分配一塊連續的記憶體空間進行資料 儲存,初始的空間大小可以預先指定也可以由vector 預...

STL序列容器 vector

二 vector vector容器是包含 t 型別元素的序列容器,和 array容器相似,不同的是 vector容器的大小可以自動增長,從而可以包含任意數量的元素 因此型別引數 t 不再需要模板引數 n。只要元素個數超出 vector 當前容量,就會自動分配更多的空間。只能在容器尾部高效地刪除或新增...