堆和棧的區別(stack and heap)
阿新 • • 發佈:2019-02-10
棧是後進先出,堆是隨便進出。
---------------------
都是一種資料結構,用於管理儲存空間,
棧用於區域性變數分配空間, 容量比較小
堆用於管理大塊資料, 容量跟系統資源有關
----------------------
只從資料結構的方面說,棧是一種有序(filo)的結構,堆是無序結構。
而程式執行中的堆與棧是不同與上面的。彙編瞭解嗎?比如下面的程式
int max(int a,int b)
{int x=0; //
if(a>b)
return a;
else
return b;
}
呼叫函式時,將資料入棧;被調函式從棧中取資料,以完成計算。採用棧的結構主要是為了呼叫資料容易清理
而堆如上面老兄說得,是不定的資料使用的空間。比如一個讀檔案的緩衝區,開始並不知道要分配多大空間,那麼棧這種固定的結構便無法滿足,只好藉助於堆這種結構了。
------------------------------
程式至少有三個資料區段:全域性資料區,堆,棧
全域性就是用存放C語言中的全域性變數那種資料,這種變數在程式結束上會自動釋放
堆段用來存放動態分配的變數,比如C++中用new分配的變數,這種變數必需手動釋放
棧段一般用來存放函式中的變數
(函式中動態分配的變數如用new分配的變數是在堆中分配的)
這種變數在出棧(如函式返回)時會自動釋放
-------------------------------
1.堆是一塊自由儲存區要比棧大很多,在堆上分配的記憶體空間不能自動釋放,必須手工釋放
棧也是記憶體中的一塊儲存區,在棧上分配的空間隨著變數或物件作用域的結束可以自動釋放
舉個例子比較好理解
CButton m_button;//這種定義變數的方式就是在棧上為m_button物件分配的記憶體空間,隨著m_button物件作用域的結束,該物件所佔的記憶體空間可以自動釋放
CButton* pButton = new CButton();
通過這種方式為pButton指向的CButton物件分配的記憶體空間就是在堆上分配的,即使該物件的作用域結束了,該儲存空間也不會自動釋放,必須手工使用delete pButton來釋放
2.如果想控制某個變數的生命期的話,為該變數在堆上分配儲存區域,例如一個多執行緒的程式中
CButton m_button;
AfxBeginThread(Func,&m_button);//將按鈕的指標作為引數傳遞給執行緒函式
//執行緒函式
UINT Func(LPVOID lparam)
{
CButton* pButton = (CButton*)lparam;
pButton->//這裡就容易出現錯誤,因為執行緒執行到這裡的時候,可能m_button所在的程式塊已經結束,也就是m_button的作用 域結束了,由於m_button是在棧上分配的儲存空間,他的作用域結束,意味著他的儲存空間也被釋放掉了,而在這裡還使用pButton來訪問已經被釋 放的記憶體,就會出現訪問非法記憶體的錯誤
return 0;
}
解決上面問題的方法可以在堆上為CButton物件分配空間,在不需要的時候再手工釋放掉
如以上程式碼可以改成
CButton * pButton = new CButton();//在堆上分配空間
AfxBeginThread(Func,pButton);
UINT Func(LPVOID lparam)
{
CButton* p = (CButton*)lparam;
p->//這樣再訪問的話就不會出現錯誤,在使用完該指標之後可以呼叫delete p;來釋放堆空間
return 0;
}
--------------------------------------------
棧是操作建立程序是為程序保留的一種記憶體資源,主要用於區域性變數的分配,相比堆而言,棧的分配要快得多。堆是由使用者程序使用malloc/free (new/delete)向系統申請得空間,需要手工釋放,比較慢。像java就是完全利用堆來管理記憶體的,而C/C++、C#等都可以從棧的使用中得到 好處!
--------------------------------------------
總結來自http://topic.csdn.net/t/20040409/14/2945507.html#
---------------------
都是一種資料結構,用於管理儲存空間,
棧用於區域性變數分配空間, 容量比較小
堆用於管理大塊資料, 容量跟系統資源有關
----------------------
只從資料結構的方面說,棧是一種有序(filo)的結構,堆是無序結構。
而程式執行中的堆與棧是不同與上面的。彙編瞭解嗎?比如下面的程式
int max(int a,int b)
{int x=0; //
if(a>b)
return a;
else
return b;
}
呼叫函式時,將資料入棧;被調函式從棧中取資料,以完成計算。採用棧的結構主要是為了呼叫資料容易清理
而堆如上面老兄說得,是不定的資料使用的空間。比如一個讀檔案的緩衝區,開始並不知道要分配多大空間,那麼棧這種固定的結構便無法滿足,只好藉助於堆這種結構了。
------------------------------
程式至少有三個資料區段:全域性資料區,堆,棧
全域性就是用存放C語言中的全域性變數那種資料,這種變數在程式結束上會自動釋放
堆段用來存放動態分配的變數,比如C++中用new分配的變數,這種變數必需手動釋放
棧段一般用來存放函式中的變數
(函式中動態分配的變數如用new分配的變數是在堆中分配的)
這種變數在出棧(如函式返回)時會自動釋放
-------------------------------
1.堆是一塊自由儲存區要比棧大很多,在堆上分配的記憶體空間不能自動釋放,必須手工釋放
棧也是記憶體中的一塊儲存區,在棧上分配的空間隨著變數或物件作用域的結束可以自動釋放
舉個例子比較好理解
CButton m_button;//這種定義變數的方式就是在棧上為m_button物件分配的記憶體空間,隨著m_button物件作用域的結束,該物件所佔的記憶體空間可以自動釋放
CButton* pButton = new CButton();
通過這種方式為pButton指向的CButton物件分配的記憶體空間就是在堆上分配的,即使該物件的作用域結束了,該儲存空間也不會自動釋放,必須手工使用delete pButton來釋放
2.如果想控制某個變數的生命期的話,為該變數在堆上分配儲存區域,例如一個多執行緒的程式中
CButton m_button;
AfxBeginThread(Func,&m_button);//將按鈕的指標作為引數傳遞給執行緒函式
//執行緒函式
UINT Func(LPVOID lparam)
{
CButton* pButton = (CButton*)lparam;
pButton->//這裡就容易出現錯誤,因為執行緒執行到這裡的時候,可能m_button所在的程式塊已經結束,也就是m_button的作用 域結束了,由於m_button是在棧上分配的儲存空間,他的作用域結束,意味著他的儲存空間也被釋放掉了,而在這裡還使用pButton來訪問已經被釋 放的記憶體,就會出現訪問非法記憶體的錯誤
return 0;
}
解決上面問題的方法可以在堆上為CButton物件分配空間,在不需要的時候再手工釋放掉
如以上程式碼可以改成
CButton * pButton = new CButton();//在堆上分配空間
AfxBeginThread(Func,pButton);
UINT Func(LPVOID lparam)
{
CButton* p = (CButton*)lparam;
p->//這樣再訪問的話就不會出現錯誤,在使用完該指標之後可以呼叫delete p;來釋放堆空間
return 0;
}
--------------------------------------------
棧是操作建立程序是為程序保留的一種記憶體資源,主要用於區域性變數的分配,相比堆而言,棧的分配要快得多。堆是由使用者程序使用malloc/free (new/delete)向系統申請得空間,需要手工釋放,比較慢。像java就是完全利用堆來管理記憶體的,而C/C++、C#等都可以從棧的使用中得到 好處!
--------------------------------------------
總結來自http://topic.csdn.net/t/20040409/14/2945507.html#