1.內存分區模型
- 代碼區:存放函數體的二進制代碼,由操作系統進行管理
- 全局區:存放全局變量和靜態變量以及常量
- 棧區:由編譯器自動分配和釋放,存放函數的參數值,局部變量等
- 堆區:由程序員分配和釋放,若沒有釋放,程序結束時由操作系統回收
2.1程序運行前
- 代碼區:
存放cpu執行的機器指令
代碼區是共享的,共享的目的是對於頻繁被執行的程序,只需要在內存中有一份代碼
代碼區是隻讀的,只讀的原因是防止程序意外的修改了它的指令
- 全局區
全局變量和靜態變量存放在這
全局區還包括了常量區,字符串常量和其他常量也存放在這
該區域在程序結束後由操作系統進行釋放
#include <iostream>
using namespace std;
/*全局變量*/
int a = 10;
const int c_a = 20;
int main()
{
/* 存放在全局區的數據有:
* 全局變量
* 靜態變量
* 常量:字符串常量和全局常量
*/
/*靜態變量,即在變量前面加上static*/
static int s_a = 20;
/*常量,包擴字符串常量和全局常量,但是不包括局部常量*/
cout << "全局變量的地址" << (&a) << endl;
cout << "靜態變量的地址" << (&s_a) << endl;
cout << "字符串常量的地址" << (&"hello world") << endl;
cout << "全局常量的地址" << (&c_a) << endl;
return 0;
}
2.2.程序運行後
- 棧區
由編譯器自動分配釋放,存放函數的參數值和局部變量等。
#include <iostream>
using namespace std;
/* 棧區的注意事項——不要返回局部變量的地址
* 棧區的數據由編譯器管理開闢和釋放
*/
int* fun(int b) //形參也存放在棧區
{
b = 10;
int a = 20; //局部變量存放在棧區,函數執行完會自動釋放
return &a;
}
int main()
{
int* p = fun();
cout << *p << endl; //第一次可以打印,因爲編譯器做了保留
cout << *p << endl; //第二次不可以打印,因爲局部變量已經被釋放
return 0;
}
- 堆區
由程序員分配釋放,如果不釋放,系統回收
#include <iostream>
using namespace std;
/* 堆區的數據只要不釋放,就一直存在
*/
int* fun()
{
int* p = new int(10); //指針本質上也是局部變量,放在棧上,指針保存的數據是放在堆上的
return p;
}
int main()
{
int* p = fun();
cout << *p << endl; //第一次可以打印,因爲編譯器做了保留
cout << *p << endl; //第二次還是可以打印
return 0;
}
3.關於什麼時候用new,什麼時候不要new
- 申請動態內存,數量不確定
- 需要的空間比較大
- 對於對象的範圍有要求
當使用new的時候,背後完成的操作
- 獲得一塊內存空間
- 調用構造函數
- 返回正確的指針
使用delete時
- 調用析構函數
- 釋放內存