資料來源
https://www.bilibili.com/video/BV1et411b73Z?p=84&vd_source=cc561849591f6a210152150b2493f6f3
核心內容
程式的記憶體模型
程式碼區
全域性區
在函式外面宣告瞭全域性變數,在main函式里面建立了區域性變數,列印了其地址:
靜態變數:在普通變數前面加一個static,屬於靜態變數。靜態變數也屬於全域性變數。
全域性區域內有:全域性變數、靜態變數、常量。
常量有:字串常量、const修飾的全域性變數(全域性常量)、const修飾區域性變數(區域性常量,不放在全域性區)。
棧區
棧區:
- 由編譯器自動分配,存放函式的引數值,區域性變數等。
- 不要返回區域性變數的地址,棧區開闢的資料由編譯器自動釋放。
- 區域性變數、形參等資料會放在棧區。
int* run() {
int a = 1;
return &a;
}
int main()
{
int* a = run();
cout << *a << endl;
cout << *a << endl;
return 0;
}
第一次能列印,是編譯器做了保留;第二次就不保留了。
堆區
堆區:
- 由程式設計師分配釋放,若程式設計師不釋放,則程式結束時由作業系統回收。
- C++中主要用於new來開闢記憶體。
int* run() {
//用new將資料開闢到堆區
int a = 1;
//指標變數p放在棧區,但是其指向的資料在堆區
int* p = new int(10);
return p;
}
int main()
{
int* a = run();
cout << *a << endl;
cout << *a << endl;
return 0;
}
new運算子
- new在堆區開闢資料
- 開闢的資料需要由程式設計師手動釋放,釋放用delete
- new返回的是開闢的資料在堆區的地址
int main()
{
int* arr = new int[10];
for (int i = 0; i < 10; i++) {
arr[i] = i + 101;
}
for (int i = 0; i < 10; i++) {
cout << arr[i] << endl;
}
//釋放堆區的陣列
delete[] arr;//必須加[],否則只會釋放一個資料
return 0;
}
發現不加[]時,剩下9個陣列元素的值雖然能訪問,但是其值變了: