變量的生存期和存儲分配

1.變量的生存期 

 變量是內存空間的一種抽象,程序中定義的每一個變量在運行時都有與之對應的內存空間。數據結構

  C++把變量佔有的內存空間的時間段稱爲生存期,分爲三類:靜態生存期、動態生存期、自動生存期函數

  • 全局變量具備靜態生存期;
  • 局部變量和函數的參數通常具備自動生存期;
  • 對於具備動態生存期的變量,其內存空間通常用new操做分配,用delete操做收回,這樣的變量稱爲動態變量,動態變量具備動態生存期。

  定義局部變量時,能夠加上存儲類型修飾符:auto、static或register來顯式地指出他們的生存週期。spa

  • 局部變量的默認存儲類型爲auto;
  • 定義static存儲類型的局部變量具備靜態生存期;
  • 定義register存儲類的局部變量也具備自動生存期,與auto存儲類的局部變量的區別在於register是建議編譯程序將相應的局部變量的空間分配在CPU的存儲器中,目的是提升對局部變量的訪問效率,固然,register類型的局部變量的存儲空間也能夠在CPU的寄存器中,或者內存中。

  在C++程序中,定義的一個變量若是沒有初始化,對於具備靜態生存期的變量(全局變量、static存儲類的局部變量),程序會隱式地自動把他們按位模式初始化爲0;對於其餘變量,編譯程序不會初始化,初始值爲內存空間已有的值,具備不肯定性。操作系統

2.做用

  • 自動的局部變量起到節省內存空間的做用,當包含auto存儲類的局部變量的函數調用結束後,其中的自動局部變量的內存就被收回了。
  • static存儲類的局部變量的做用是,能在函數調用時得到上一次調用結束時該局部變量的值,即能在函數屢次調用之間得以保留。

特別注意的是,static存儲類的局部變量若是在定義中初始化,則該初始化只在函數第一次調用時進行,後面的調用中再也不初始化,它的值爲上一次調用結束時的值,受函數封裝的保護。code

3.存儲的分配  

  當一個程序運行時,操做系統會爲其分配一個內存空間,包括四個部分:靜態數據區(static data)、代碼區(code)、棧區(stack)和堆區(heap,或稱自由存儲區,free store),以下圖所示(不一樣操做系統的順序會不一樣)。blog

  在程序的內存空間中:內存

  • 靜態數據區用於全局變量、static存儲類的局部變量以及變量的內存分配;
  • 代碼區用於存放程序的指令,對於C++,代碼區存放的是全部函數的代碼;
  • 棧區用於auto存儲類的局部變量、函數的參數,及函數調用時的有關信息(如函數的返回地址等)的內存分配;
  • 堆區用於動態變量的內存分配

   靜態數據區和代碼區的大小是固定的,而棧區和堆區的大小將會隨着程序的運行不斷變化,不過,操做系統對於程序的棧區和堆區的最大值有必定的限制。編譯

4.基於棧的函數調用的實現

  函數調用是經過棧來實現的,棧是一種元素個數可變的線性數據結構。其元素的增長和減小隻能在某一端進行。效率

  1. 在C++函數調用時,調用者在棧中爲形參函數返回地址分配空間,並將函數中實參的值和調用後的返回地址放入所分配的棧空間中;
  2. 函數調用中,被調用的函數在棧中爲自動存儲類的局部變量分配空間,並從棧中(經過形參)得到調用者提供的數據(實參的值);
  3. 函數調用後,被調用者釋放局部變量的棧空間,並根據棧空間的返回地址返回到調用點(存儲返回地址的棧空間將被釋放);
  4. 調用者釋放形參佔用的的棧空間,而後繼續執行調用以後的操做。

堆棧順序:形參->函數返回地址->函數內的auto局部變量變量

   

相關文章
相關標籤/搜索