1. 程式人生 > >堆和棧的區別(stack and heap)

堆和棧的區別(stack and heap)

棧是後進先出,堆是隨便進出。
---------------------
都是一種資料結構,用於管理儲存空間,  
  棧用於區域性變數分配空間,   容量比較小  
  堆用於管理大塊資料,   容量跟系統資源有關
----------------------
只從資料結構的方面說,棧是一種有序(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#