解析C++對象在堆棧區的析構
關于堆棧區和析構函數,我想大家都已經很熟悉了。下面介紹的是C++對象在堆棧區的析構。
作為一個C++程序員,區別于其他面向對象語言其中最敏感的就是對new(malloc)和delete(free)這兩個關鍵字了。
今天在閱讀老大的代碼的時候,在COM對象的重復賦值的時候發現在對一個vector重新分配的insert新元素的時候,沒有先clear掉。自己以前在用STL的容器的時候總是在開頭和***調用clear,但是進過實驗和調試之后發現,含有vector的對象在析構的時候就是不做vector.clear()的話,vector中的元素也能析構。
后來稍微一想,就發現自己之前的想法是多愚蠢,STL的容器都是C++對象,既然是對象肯定會在自己的析構函數中做一些清理,如果連這些都沒有的話,那STL也不會發展成C++***的一個庫了。
由此又想到了很多,vector在clear到底干了什么,從匯編的角度來說,在棧上的一切變量都是不會導致內存泄露的,那么vector是否真的不用去調用clear呢?錯,vector的元素肯定不會是建立在棧上的,而是建立在堆上的。為什么,建立在棧上的數組大小肯定是在編譯時候就確定的,為什么?想到了在學校時候的一個非常典型的例子:
- int x;
- scanf("%d", &x);
- char ch[x];
試圖通過輸入一個數字來分配對象的x個字符,這是不行的,為什么?當時老師只說這是在編譯時期確定的,不能動態確定,只能寫成
- int x;
- scanf("%d", &x);
- char* ch = new char[x];
這已經是分配在堆上了,以后再運行期動態確定。那到底為什么棧上的空間不能在運行期動態確定呢?從匯編的角度來理解就容易多了:棧上能夠移動的元素總是在棧頂的,無非就是Push,Pop
- char ch[x];
- int i,j;
試想一下,面對這樣的動態分配,該怎樣生成指令來制定棧的建立呢,由于在建立棧的時候每一個指令在棧中需要占用的大小,堆中就不一樣了,堆中內存可以是不連續的,不用遵循FILO的棧原則,所以是相當靈活的。
現在來看為什么STL的容器都是建立在堆上的,STL的容器往往都是可以調整大小的,試問建立在棧上的元素,如何能保證它在任何時候都能調整大小呢,除非在任何時候都能保證它在棧頂,顯然這是不現實的!
本文地址:http://blog.csdn.net/woshishenguanyear/archive/2011/06/13/6542527.aspx
【編輯推薦】