最近學習了Vector的使用,在通用函數的背后,你了解它的工作機理么,你能回答下面幾個問題么。如何不慎清楚,請看下文之簡單剖析。后續問題和疑問,將在文后補充。
Q:是嵌套的vector數組中的二級vector在一級vector刪除時需不需要手動刪除?
A:釋放遵循有內到外,只有vector存的是指針時才需要釋放,其它不需要釋放
Q:erase clear 能釋放內存么?
earse 是不釋放內存的 僅僅清理數據
可是使用clear釋放vector內存有是問題的,可參考c++標准:
clear只是將vector的size置零,可是並不保證capacity為零,因此clear並不能釋放vector已經申請的內存。可使用vector<T>().swap(x)完成釋放內存的操作。
考慮用swap()來幫助釋放內存‘
C++ vector 內存分配與回收機制
https://blog.csdn.net/sinat_33718563/article/details/77869145
https://blog.csdn.net/wskzgz/article/details/113122684 // c++ vector內存分配、內存分布堆棧
1. vector內存增長
vector所有的內存相關問題都可以歸結於它的內存增長策略。vector有一個特點就是:內存空間只會增長不會減少。vector有兩個函數,一個是capacity(),
返回對象緩沖區(vector維護的內存空間)實際申請的空間大小,另一個size(),返回當前對象緩沖區存儲數據的個數。
對於vector來說,capacity是永遠大於等於size的,但capacity和size相等時,vector就會擴容,capacity變大。
比如說vector最常用的push_back操作,它的整個過程是怎么一個機制呢?這個問題經常在面試中出現。
這個問題其實很簡單,在調用push_back時,若當前容量已經不能夠放入新的元素(capacity=size),那么vector會重新申請一塊內存,把之前的內存里的元素拷貝到新的內存當中,
然后把push_back的元素拷貝到新的內存中,最后要析構原有的vector並釋放原有的內存。
所以說這個過程的效率是極低的,為了避免頻繁的分配內存,C++每次申請內存都會成倍的增長,例如之前是4,那么重新申請后就是8,以此類推。當然不一定是成倍增長
在調用push_back時,每次執行push_back操作,相當於底層的數組實現要重新分配大小;
這種實現體現到vector實現就是每當push_back一個元素,都要重新分配一個大一個元素的存儲,
然后將原來的元素拷貝到新的存儲,之后在拷貝push_back的元素,最后要析構原有的vector並釋放原有的內存。
2. 內存釋放
就像前面所說的,vector的內存空間是只增加不減少的,我們常用的操作clear()和erase(),實際上只是減少了size(),清除了數據,並不會減少capacity,所以內存空間沒有減少。
那么如何釋放內存空間呢,正確的做法是swap()操作。
標准模板如下
template < class T >
void ClearVector( vector< T >& vt )
{
vector< T > vtTemp;
veTemp.swap( vt );
}
例子:
vector<int> nums;
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
vector<int>().swap(nums); //或者nums.swap(vector<int> ())
3.總結
由上可見,vector雖然是動態數組,但是本質上和數組沒什么區別,頻繁的銷毀新建,效率很低,所以正確的做法是新建vector的時候初始化一個合適的大小(笑),
回到了數組的老路上。不過之后可以動態變化還是很方便,而且還有很多好用的函數。vecotr是動態數組,顧名思義他可以動態的增加自己的長度。
Vector系列內存布局分析
https://www.leadroyal.cn/p/181/
https://lunatic.blog.csdn.net/article/details/88556426