您好,登錄后才能下訂單哦!
本篇內容介紹了“C++中的內存分區知識點講解”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
一、分區的意義
二、代碼區
1、定義
2、特點
三、全局區
1、定義
2、特點
3、相關代碼
1)全局變量
2)靜態變量
四、棧區——程序運行后
1、定義
2、相關代碼
五、堆區——運行后
1、定義
2、相關代碼和運行結果
在講分區前,先談談內存分區的意義,也就是為什么程序要進行分區?
筆者認為這是為了編程的靈活性,因為將內存分區后,不同區域的內存,相關的數據就有的不同的生命周期。以筆者之前的一篇算法復雜度的blog中提到棧幀空間為例,在此就是指棧區,而棧區多指非main函數調用的內存(相關參數等),當非main函數調用結束后,這塊的內存就會清空釋放。而這里的數據就可以和在main函數中的數據有不同的生命周期。
存放函數體內的二進制代碼,由操作系統進行管理
注意:代碼區是在程序運行前的內存區域,除了代碼區,運行前還有全局區。代碼區存放的二進制代碼其實就是編譯器(cpu)執行的指令。
1)代碼區是共享的,之所以共享是因為對于被頻繁執行的程序,只需要在內存中存放一份代碼即可。避免內存過多的浪費。
2)代碼區是只讀的,原因是防止程序意外地修改了它的指令。
前面提到全局區,也在程序執行前。
存放全局變量和靜態變量以及常量
該區域的數據在程序結束后由操作系統釋放。
#include<iostream> #include<string> using namespace std; // 全局變量 int g_a = 10; int g_b = 10; int main() { // 全局區 // 全局變量、靜態變量、常量 // 創建普通局部變量 int a = 10; int b = 10; cout << "局部變量a的地址為: " << (int)&a << endl << "局部變量b的地址為: " << (int)&b << endl; cout << "全局變量g_a的地址為: " << (int)&g_a << endl; cout << "全局變量g_b的地址為: " << (int)&g_b << endl; system("pause"); return 0; }
程序執行結果:
從結果看,局部變量和全局變量存放的地址顯然有很大的不同,而從a和b以及g_a和g_b的地址來看,全局變量和局部變量相鄰的變量的內存地址是相近,從結果看是差了4,這是因為單位int占4個字節。
// 靜態變量 在普通變量前面加static,屬于靜態變量 static int s_a = 10; static int s_b = 10; cout << "靜態變量s_a的地址為: " << (int)&s_a << endl; cout << "靜態變量s_b的地址為: " << (int)&s_b << endl;
將上述代碼加入到前面的main函數中,運行得到如下結果
3)常量(不包含局部常量即const修飾的局部變量)
#include<iostream> #include<string> using namespace std; // 全局變量 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 << "局部變量b的地址為: " << (int)&b << endl; cout << "全局變量g_a的地址為: " << (int)&g_a << endl; cout << "全局變量g_b的地址為: " << (int)&g_b << endl; // 靜態變量 在普通變量前面加static,屬于靜態變量 static int s_a = 10; static int s_b = 10; cout << "靜態變量s_a的地址為: " << (int)&s_a << endl; cout << "靜態變量s_b的地址為: " << (int)&s_b << endl; // 常量 // 字符串常量 cout << "字符串常量的地址為: " << (int)&"hello world" << endl; //const修飾的變量 // const修飾的全局變量、const修飾的局部變量 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; }
由編譯器自動分配釋放,存放函數的參數值,局部變量等
注意 :不要返回局部變量的地址,棧區開辟的數據由編譯器自動釋放。
#include<iostream> #include<string> using namespace std; // 棧區注意事項——不要返回局部變量的地址 // 棧區的數據由編譯器管理開辟和釋放 int* func(int b) // 形參數據也會放在棧區 { b = 100; int a = 10; // 局部變量 存放在棧區,棧區的數據在函數執行完后自動釋放 return &a; // 返回局部變量的地址 } int main() { // 接收func函數的返回值 int* p = func(1); cout << *p << endl; // 第一次可以打印正確數字,是因為編譯器做了保留 cout << *p << endl; // 第二次就不保留了 system("pause"); return 0; }
由程序員分配釋放,若程序員不釋放,程序結束時由操作系統回收
c++中主要利用new在堆區開辟內存
#include<iostream> #include<string> using namespace std; int* func() { // 利用new關鍵字 可以將數據開辟到堆區 // 指針 本質也是局部變量,放在棧上,指針保存的數據是放在堆區 int* p = new int(10); return p; } int main() { // 在堆區開辟數據 int* p = func(); cout << *p << endl; cout << *p << endl; cout << *p << endl; cout << *p << endl; system("pause"); return 0; }
“C++中的內存分區知識點講解”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。