一,? ?內存分配模型
內存總共有四個分區
1? 代碼區
主要用來存儲二進制代碼,由操作系統進行管理
2? 棧區
由編譯器自己進行釋放和分配,例如函數的傳遞的參數,局部變量,const修飾的局部常量等等....
3? 堆區
由程序員自己分配和釋放,如果程序員沒有進行釋放,則由操作系統到最后自行釋放
4? 全局區
主要存儲全局變量,靜態常量,字符串常量和全局常量(const修飾)
分區的意義:
不同區域存放不同的數據,可以控制這些數據不同的生命周期,使得內存靈活
二,? ?代碼區和全局區
代碼區和全局區是在程序運行之前就已經開始分區了
1. 代碼區
主要存放的是CPU執行的機器指令
代碼區的特點
1? 共享性:在我們點擊編譯運行按鈕的時候都會生成一個可執行的.exe文件,這個文件進行多次點擊會彈出多個窗口,然后這里面的數據是互通公用的,計算機并不會重新開辟一個內存再次進行存儲
2? 只讀性:比如充值系統的數據是不可以隨意更改的,要是給予更改的話,商家無疑是虧損很大的,所以這個充值系統不可以隨意的更改
2. 全局區
主要存放全局變量,靜態常量,字符串常量和全局常量(const修飾)
全局變量-----不在函數體內部的變量
靜態常量-----加上static關鍵字的變量
字符串,const修飾的全局常量
以上可以根據設置變量在不同的區域,來輸出他們對應的地址來觀察判斷是否是屬于同一區域的
#include<iostream>using namespace std;//全局變量
int a;//const 修飾的全局常量
const int b1 = 0;
const int b2 = 0;int main() {//const修飾的局部變量const int a1 = 0;const int a2 = 0;//static修飾的靜態變量static int c1;static int c2;cout << "字符串地址:" << (int)&"hello world" << endl;cout << "static地址:" << (int)&c1 << endl;cout << "static地址:" << (int)&c2 << endl;cout << "const局部地址:" << (int)&a1 << endl;cout << "const局部地址:" << (int)&a2 << endl;cout << "const全局地址:" << (int)&b1 << endl;cout << "const全局地址:" << (int)&b2 << endl;}
字符串地址:995208456
static地址:995221940
static地址:995221944
const局部地址:-2081424876
const局部地址:-2081424844
const全局地址:995208112
const全局地址:995208116D:\porject\C++\x64\Debug\C++.exe (進程 3144)已退出,代碼為 0 (0x0)。
要在調試停止時自動關閉控制臺,請啟用“工具”->“選項”->“調試”->“調試停止時自動關閉控制臺”。
按任意鍵關閉此窗口. . .
可以看到運行出來的控制窗口顯示的地址字符串,static,const修飾的全局地址都是十分接近的,但是const修飾的局部地址是離很遠的,這么說明const修飾的局部變量不是在全局區
三,棧區和堆區
棧區和堆區,這兩個區域是程序運行后才產生的
1. 棧區
棧區是由編譯器自己分配和釋放的,一般都是局部變量,函數的傳參值...
注意事項:1? 不要返回局部變量的地址,棧區開辟的數據由編譯器自己決定釋放
#include<iostream>using namespace std;int* fun() {int b = 10;return &b;
}int main() {int* p = fun();cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;int a = 1;cout << *p << endl;return 0;
}
當我們不用VS2022,用Dev-C++來運行這個代碼的時候,運行出來的結果是這樣的
10
0
0
0
0
0
0--------------------------------
Process exited after 0.791 seconds with return value 0
請按任意鍵繼續. . .
運行出來的結果后面都是未知量,這個時候我們可以知道,經典的C++編譯器只會給我們保留一次這個值,并不會一直保留,所以后面答應出來的值都是0
2. 堆區
堆區的知識點我們只需要知道,這個區域是我們程序員自己去釋放和開辟區域的,然后C++喜歡用new運算符來進行開辟內存和釋放內存
new運算符的使用
1.? 利用new運算符開辟一個變量并且賦值
int* p = new int(10);
delete p;
2.? 利用new運算符開辟一個數組
int* p = new int[10];
delete []p;
四,? 總結
1? 內存的分區類型
1 棧區? 2 代碼區? 3 全局區? 4 堆區
2? 每個內存分區的作用
(づ。????。)づ? 代碼區:
(a)? 主要存放二進制的機器指令
(b)? 兩個特點:共享和只讀特性
(ノ?ヮ?)ノ:・゚?? ?全局區:
(a)? 主要存放全局變量,靜態常量,const修飾的全局常量,需要注意的是const修飾的常量不是存放在全局區域,可以通過打印對應的地址來判斷他們的分區是否一致
(。・ω・。)ノ?? ? ? ?棧區:
(a)? 棧區主要是編譯器自己進行釋放和分配內存,常見的由函數傳遞的參數,局部變量...等一系列生命周期較短的變量
Σ(°△°|||)︴? ? ? ? 堆區:
(a)? 堆區主要是程序員自己進行分配和釋放內存,最后沒有釋放的內存,等到程序結束由操作系統進行釋放內存
3? new操作運算符的使用
主要就是分配變量和數組在堆區
int* p = new int(10);
delete p;
int* p = new int[10];
delete []p;