C++內(nèi)存四區(qū)模型使用及說明
1 內(nèi)存分區(qū)模型
C++程序在執(zhí)行時,將內(nèi)存大方向劃分為4個區(qū)域
- 代碼區(qū):存放函數(shù)體的二進制代碼,由操作系統(tǒng)進行管理的
- 全局區(qū):存放全局變量和靜態(tài)變量以及常量
- 棧區(qū):由編譯器自動分配釋放, 存放函數(shù)的參數(shù)值,局部變量等
- 堆區(qū):由程序員分配和釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收
內(nèi)存四區(qū)意義:
不同區(qū)域存放的數(shù)據(jù),賦予不同的生命周期, 給我們更大的靈活編程
1.1 程序運行前
? 在程序編譯后,生成了exe可執(zhí)行程序,未執(zhí)行該程序前分為兩個區(qū)域
? 代碼區(qū):
- ? 存放 CPU 執(zhí)行的機器指令
- 代碼區(qū)是共享的,共享的目的是對于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可
- ? 代碼區(qū)是只讀的,使其只讀的原因是防止程序意外地修改了它的指令
? 全局區(qū):
- 該區(qū)域的數(shù)據(jù)在程序結(jié)束后由操作系統(tǒng)釋放.
? 全局變量和靜態(tài)變量存放在此.
全局變量注意事項:
1、在函數(shù)外部定義的變量,使用范圍從定義的地方開始到——>本源文件結(jié)束
2、如果沒給初始值,會自動初始化為0
3、當(dāng)全局變量名稱和局部變量名稱相同時,使用的是局部變量
4、若使用的全局變量定義于其他的源文件中,可以使用extern關(guān)鍵字聲明【extern int a;】
靜態(tài)變量注意事項:static關(guān)鍵字
1、static作用全局變量之前,稱為靜態(tài)全局變量,限制其他源文件使用(僅限本源文件使用)
2、static作用局部變量之前,稱為靜態(tài)局部變量,只初始化一次,函數(shù)結(jié)束后空間不會釋放
3、static作用函數(shù)之前,稱為靜態(tài)函數(shù),僅限本文件使用
全局區(qū)還包含了常量區(qū), 字符串常量和其他常量也存放在此.
示例:
//全局變量
int g_a = 10;
int g_b = 10;
//全局常量
const int c_g_a = 10;
const int c_g_b = 10;
int main() {
//局部變量
int a = 10;
int b = 10;
//打印地址
cout << "局部變量a地址為: " << (int)&a << endl;
cout << "局部變量b地址為: " << (int)&b << endl;
cout << "全局變量g_a地址為: " << (int)&g_a << endl;
cout << "全局變量g_b地址為: " << (int)&g_b << endl;
//靜態(tài)變量——static關(guān)鍵字
1、static作用全局變量之前,稱為靜態(tài)全局變量,限制其他源文件使用(僅限本源文件使用)
2、static作用局部變量之前,稱為靜態(tài)局部變量,只初始化一次,函數(shù)結(jié)束后空間不會釋放
3、static作用函數(shù)之前,稱為靜態(tài)函數(shù),僅限本文件使用
static int s_a = 10;
static int s_b = 10;
cout << "靜態(tài)變量s_a地址為: " << (int)&s_a << endl;
cout << "靜態(tài)變量s_b地址為: " << (int)&s_b << endl;
cout << "字符串常量地址為: " << (int)&"hello world" << endl;
cout << "字符串常量地址為: " << (int)&"hello world1" << endl;
cout << "全局常量c_g_a地址為: " << (int)&c_g_a << endl;
cout << "全局常量c_g_b地址為: " << (int)&c_g_b << endl;
const int c_l_a = 10;
const int c_l_b = 10;
cout << "局部常量c_l_a地址為: " << (int)&c_l_a << endl;
cout << "局部常量c_l_b地址為: " << (int)&c_l_b << endl;
system("pause");
return 0;
}
- 打印結(jié)果:

總結(jié):
- C++中在程序運行前分為全局區(qū)和代碼區(qū)
- 代碼區(qū)特點是共享和只讀
- 全局區(qū)中存放全局變量、靜態(tài)變量、常量
- 常量區(qū)中存放 const修飾的全局常量 和 字符串常量
1.2 程序運行后
?棧區(qū):
? 由編譯器自動分配釋放, 存放函數(shù)的參數(shù)值,局部變量等
? 注意事項:不要返回局部變量的地址,棧區(qū)開辟的數(shù)據(jù)由編譯器自動釋放
示例:
int * func(int b)//形參數(shù)據(jù)也會存放棧區(qū)
{
b=100;
int a = 10;//局部變量存放棧區(qū),棧區(qū)數(shù)據(jù)在函數(shù)執(zhí)行完后自動釋放
return &a;
}
int main() {
int *p = func(1);
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
?堆區(qū):
? 由程序員分配釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收
? 在C++中主要利用new在堆區(qū)開辟內(nèi)存
示例:
int* func()
{
//利用new關(guān)鍵字可以將數(shù)據(jù)開辟到堆區(qū)。new int(10)返回的是10這個數(shù)據(jù)的地址
//指針 本質(zhì)也是局部變量,指針指向堆區(qū)數(shù)據(jù)的地址,==新開辟一片存儲空間==將其地址存在棧上
int* a = new int(10);
return a;
}
int main() {
int *p = func();
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
總結(jié):
堆區(qū)數(shù)據(jù)由程序員管理開辟和釋放
堆區(qū)數(shù)據(jù)利用new關(guān)鍵字進行開辟內(nèi)存
1.3 new操作符
? C++中利用new操作符在堆區(qū)開辟數(shù)據(jù)
? 堆區(qū)開辟的數(shù)據(jù),由程序員手動開辟,手動釋放,釋放利用操作符 delete
? 語法: new 數(shù)據(jù)類型
? 利用new創(chuàng)建的數(shù)據(jù),會返回該數(shù)據(jù)對應(yīng)的類型的指針
示例1: 基本語法
int* func()
{
//在堆區(qū)創(chuàng)建整型數(shù)據(jù)
//new返回是 該數(shù)據(jù)類型的指針
int* a = new int(10);//10代表創(chuàng)建的整型數(shù)據(jù)為10
return a;
}
int main() {
int *p = func();
cout << *p << endl;
cout << *p << endl;
//堆區(qū)的數(shù)據(jù) 由程序員管理開辟, 釋放
//利用delete釋放堆區(qū)數(shù)據(jù)
delete p;
//cout << *p << endl; //報錯,釋放的空間不可訪問
system("pause");
return 0;
}
示例2:開辟數(shù)組
//堆區(qū)開辟數(shù)組
int main() {
//創(chuàng)建10整型數(shù)據(jù)的數(shù)組,在堆區(qū)
int* arr = new int[10];//10代表數(shù)組有10個元素
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;
}
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//釋放數(shù)組 delete 后加 []
delete[] arr;
system("pause");
return 0;
}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++實現(xiàn)LeetCode(56.合并區(qū)間)
這篇文章主要介紹了C++實現(xiàn)LeetCode(56.合并區(qū)間),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++ 數(shù)據(jù)結(jié)構(gòu)之水洼的數(shù)量算法
這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)之水洼的數(shù)量算法的相關(guān)資料,需要的朋友可以參考下2017-06-06
詳解C語言中sizeof如何在自定義函數(shù)中正常工作
在main函數(shù)中,sizeof是可以正常工作的,但是在自定義函數(shù)中就不可以了。所以本文將為大家詳細(xì)講解一下如何解決這一問題,感興趣的可以了解一下2022-05-05
關(guān)于STL中l(wèi)ist容器的一些總結(jié)
list就是數(shù)據(jù)結(jié)構(gòu)中的雙向鏈表(根據(jù)sgi stl源代碼),因此它的內(nèi)存空間是不連續(xù)的,通過指針來進行數(shù)據(jù)的訪問,這個特點使得它的隨即存取變的非常沒有效率,因此它沒有提供[]操作符的重載2013-09-09

