c++基礎複習——程序的內存模型

1.內存分區模型

  • 代碼區:存放函數體的二進制代碼,由操作系統進行管理
  • 全局區:存放全局變量和靜態變量以及常量
  • 棧區:由編譯器自動分配和釋放,存放函數的參數值,局部變量等
  • 堆區:由程序員分配和釋放,若沒有釋放,程序結束時由操作系統回收

2.1程序運行前

  • 代碼區:

       存放cpu執行的機器指令

       代碼區是共享的,共享的目的是對於頻繁被執行的程序,只需要在內存中有一份代碼

       代碼區是隻讀的,只讀的原因是防止程序意外的修改了它的指令

  • 全局區

      全局變量和靜態變量存放在這

      全局區還包括了常量區,字符串常量和其他常量也存放在這

      該區域在程序結束後由操作系統進行釋放

#include <iostream>
using namespace std;
/*全局變量*/
int a = 10;
const int c_a = 20;

int main() 
{
    /* 存放在全局區的數據有:
     * 全局變量
     * 靜態變量
     * 常量:字符串常量和全局常量
     */
    
    /*靜態變量,即在變量前面加上static*/
    static int s_a = 20;
    /*常量,包擴字符串常量和全局常量,但是不包括局部常量*/
    
    cout << "全局變量的地址" << (&a) << endl;
    cout << "靜態變量的地址" << (&s_a) << endl;
    cout << "字符串常量的地址" << (&"hello world") << endl;
    cout << "全局常量的地址" << (&c_a) << endl;

    return 0;

}

2.2.程序運行後

  • 棧區

由編譯器自動分配釋放,存放函數的參數值和局部變量等。

#include <iostream>
using namespace std;
/* 棧區的注意事項——不要返回局部變量的地址
 * 棧區的數據由編譯器管理開闢和釋放
 */
int* fun(int b) //形參也存放在棧區
{
    b = 10; 
    int a = 20; //局部變量存放在棧區,函數執行完會自動釋放
    return &a;
}

int main() 
{
    int* p = fun();
    cout << *p << endl; //第一次可以打印,因爲編譯器做了保留
    cout << *p << endl; //第二次不可以打印,因爲局部變量已經被釋放

    return 0;
}
  • 堆區

由程序員分配釋放,如果不釋放,系統回收

#include <iostream>
using namespace std;
/* 堆區的數據只要不釋放,就一直存在
 */
int* fun() 
{
    int* p = new int(10); //指針本質上也是局部變量,放在棧上,指針保存的數據是放在堆上的
    return p;
}

int main() 
{
    int* p = fun();
    cout << *p << endl; //第一次可以打印,因爲編譯器做了保留
    cout << *p << endl; //第二次還是可以打印

    return 0;
}

3.關於什麼時候用new,什麼時候不要new

  • 申請動態內存,數量不確定
  • 需要的空間比較大
  • 對於對象的範圍有要求

當使用new的時候,背後完成的操作

  1. 獲得一塊內存空間
  2. 調用構造函數
  3. 返回正確的指針

使用delete時

  1. 調用析構函數
  2. 釋放內存
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章