1. 程式人生 > >VC++ 記憶體機理的個人理解(二)——堆和棧

VC++ 記憶體機理的個人理解(二)——堆和棧

     說完了地址和指標,我們來說說堆和棧的不同,在此之前,感謝Polaris給我的幫助,在這個問題是他給我講了很多,也舉了很多例子,讓我懂了很多關於堆疊的東西。

    首先,關於堆和棧的資料結構小凡就不多說什麼了,是先進先出還是後進先出也不是我們討論的範圍。

    但是有一點還是很不一樣的,棧記憶體空間一般而言要比堆記憶體空間小很多,對windows來說,一個thread的棧記憶體是1M,但是堆記憶體可以按照你的需要申請甚至好幾個G(當然到時候要用硬碟快取這個就是題外話了)。

    從編碼上看,也是有一些區別的。

    在以上的程式碼中,intInStack就是存放在棧記憶體中的0,而intInHeap就是一個指向堆記憶體中的0的指標。沒錯,這就是C++分配堆記憶體和棧記憶體在程式碼上的區別,對C++來說,不管是值型別還是引用型別,都是通過這樣的方式來申請堆記憶體和棧記憶體。而且,有一點更重要:堆記憶體是需要自維護的!delete intInHeap;如果不寫,那這塊記憶體就永遠不釋放,甚至程式關閉了也不會釋放,這就是有名的記憶體溢位問題。

    題外話,C#中的堆疊記憶體分配方式:

C#中,除了class以外,其它型別其實都是值型別,包括struct。小凡想很多人都認為new的就是分配在堆記憶體上了,事實上:

int i = 0;
int i2 = new int();

int i3 = new Int32();

    這三行程式碼是等價的,它們都是值型別,所以,並不是C#中的new就保證在堆記憶體上。

    其實很簡單,C#中是通過class宣告的變數,就是引用型別,引用型別一律放在堆記憶體中。其它型別都是值型別,一律放在棧記憶體中

    什麼?你問Int32?仔細看看,它是struct,你試試繼承Int32看看就知道了。為什麼要new?因為如果不new一下,所有變數都出於未分配狀態,就好像是一個沒有分配目標記憶體地址的指標,肯定是不能使用的。