C++內(nèi)存四區(qū)模型使用及說明
1 內(nèi)存分區(qū)模型
C++程序在執(zhí)行時(shí),將內(nèi)存大方向劃分為4個(gè)區(qū)域
- 代碼區(qū):存放函數(shù)體的二進(jìn)制代碼,由操作系統(tǒng)進(jìn)行管理的
- 全局區(qū):存放全局變量和靜態(tài)變量以及常量
- 棧區(qū):由編譯器自動(dòng)分配釋放, 存放函數(shù)的參數(shù)值,局部變量等
- 堆區(qū):由程序員分配和釋放,若程序員不釋放,程序結(jié)束時(shí)由操作系統(tǒng)回收
內(nèi)存四區(qū)意義:
不同區(qū)域存放的數(shù)據(jù),賦予不同的生命周期, 給我們更大的靈活編程
1.1 程序運(yùn)行前
? 在程序編譯后,生成了exe可執(zhí)行程序,未執(zhí)行該程序前分為兩個(gè)區(qū)域
? 代碼區(qū):
- ? 存放 CPU 執(zhí)行的機(jī)器指令
- 代碼區(qū)是共享的,共享的目的是對于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可
- ? 代碼區(qū)是只讀的,使其只讀的原因是防止程序意外地修改了它的指令
? 全局區(qū):
- 該區(qū)域的數(shù)據(jù)在程序結(jié)束后由操作系統(tǒng)釋放.
? 全局變量和靜態(tài)變量存放在此.
全局變量注意事項(xiàng):
1、在函數(shù)外部定義的變量,使用范圍從定義的地方開始到——>本源文件結(jié)束
2、如果沒給初始值,會(huì)自動(dòng)初始化為0
3、當(dāng)全局變量名稱和局部變量名稱相同時(shí),使用的是局部變量
4、若使用的全局變量定義于其他的源文件中,可以使用extern關(guān)鍵字聲明【extern int a;】
靜態(tài)變量注意事項(xiàng):static關(guān)鍵字
1、static作用全局變量之前,稱為靜態(tài)全局變量,限制其他源文件使用(僅限本源文件使用)
2、static作用局部變量之前,稱為靜態(tài)局部變量,只初始化一次,函數(shù)結(jié)束后空間不會(huì)釋放
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é)束后空間不會(huì)釋放
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++中在程序運(yùn)行前分為全局區(qū)和代碼區(qū)
- 代碼區(qū)特點(diǎn)是共享和只讀
- 全局區(qū)中存放全局變量、靜態(tài)變量、常量
- 常量區(qū)中存放 const修飾的全局常量 和 字符串常量
1.2 程序運(yùn)行后
?棧區(qū):
? 由編譯器自動(dòng)分配釋放, 存放函數(shù)的參數(shù)值,局部變量等
? 注意事項(xiàng):不要返回局部變量的地址,棧區(qū)開辟的數(shù)據(jù)由編譯器自動(dòng)釋放
示例:
int * func(int b)//形參數(shù)據(jù)也會(huì)存放棧區(qū)
{
b=100;
int a = 10;//局部變量存放棧區(qū),棧區(qū)數(shù)據(jù)在函數(shù)執(zhí)行完后自動(dòng)釋放
return &a;
}
int main() {
int *p = func(1);
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
?堆區(qū):
? 由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)由操作系統(tǒng)回收
? 在C++中主要利用new在堆區(qū)開辟內(nèi)存
示例:
int* func()
{
//利用new關(guān)鍵字可以將數(shù)據(jù)開辟到堆區(qū)。new int(10)返回的是10這個(gè)數(shù)據(jù)的地址
//指針 本質(zhì)也是局部變量,指針指向堆區(qū)數(shù)據(jù)的地址,==新開辟一片存儲(chǔ)空間==將其地址存在棧上
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)鍵字進(jìn)行開辟內(nèi)存
1.3 new操作符
? C++中利用new操作符在堆區(qū)開辟數(shù)據(jù)
? 堆區(qū)開辟的數(shù)據(jù),由程序員手動(dòng)開辟,手動(dòng)釋放,釋放利用操作符 delete
? 語法: new 數(shù)據(jù)類型
? 利用new創(chuàng)建的數(shù)據(jù),會(huì)返回該數(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; //報(bào)錯(cuò),釋放的空間不可訪問
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個(gè)元素
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é)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(56.合并區(qū)間)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(56.合并區(qū)間),本篇文章通過簡要的案例,講解了該項(xiàng)技術(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語言實(shí)現(xiàn)猜數(shù)字游戲的兩種方法
猜數(shù)字小游戲是我們大多數(shù)人學(xué)習(xí)C語言時(shí)都會(huì)了解到的一個(gè)有趣的C語言小游戲,本文就詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
詳解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ù)的,通過指針來進(jìn)行數(shù)據(jù)的訪問,這個(gè)特點(diǎn)使得它的隨即存取變的非常沒有效率,因此它沒有提供[]操作符的重載2013-09-09
Qt編寫自定義控件實(shí)現(xiàn)抽獎(jiǎng)轉(zhuǎn)盤
這篇文章主要為大家詳細(xì)介紹了Qt編寫自定義控件實(shí)現(xiàn)抽獎(jiǎng)轉(zhuǎn)盤,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
詳解如何利用C++實(shí)現(xiàn)一個(gè)反射類
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)一個(gè)反射類,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03

