前言
第9天是一個通訊錄管理系統案例,現在了解程序的內存分區,C++程序在執行時,將內存大方向分為了4個區域,分別是代碼區、全局區、棧區、堆區,分區的目的就是為了更加靈活的編程。
代碼區 and 全局區(程序前)
在程序編譯后,生成了exe可執行文件,未執行該程序前分為兩個區:代碼區和全局區
代碼區:
存放CPU執行的指令
代碼區是共享的,共享的目的是對于頻繁被執行的程序,只需要在內存中有一份代碼即可
代碼區是只讀的,使其只讀的原因是防止程序意外地修改了它的指令,
全局區:
全局變量和靜態變量存放在此
全局變量還包含了常量區,字符串常量和其他常量
該區域的數據在程序結束后由操作系統釋放
#include<iostream>
using namespace std;//全局變量
int g_a = 10;
const int c_g_a = 10; //const修飾的全局變量,相當于全局常量int main()
{//局部變量int l_a = 10;cout<< "局部變量l_a的地址:" <<(int)&l_a<<endl;//靜態變量 static int s_a = 10;cout<< "靜態變量s_a的地址:" <<(int)&s_a<<endl;//常量//字符串常量cout<< "字符串常量的地址" <<(int)&"hello world"<<endl;//const修飾的變量//const修飾的全局變量cout<< "const修飾的全局變量c_g_a的地址:" <<(int)&c_g_a<<endl;
}
棧區and堆區(程序運行后)
棧區:
由編譯器自動分配釋放,存放函數的參數值,局部變量
注意:不要返回局部變量的地址,棧區開辟的數據由編譯器自動編譯
堆區:
由程序員分配釋放,若程序不釋放,程序結束時由操作系統回收
在C++中主要利用new在堆區中開辟內存
#include<iostream>
using namespace std;int* func(int b) //形參數據也會存放在棧區
{b=100;int a = 10; //局部變量 存放在棧區,棧區的數據在函數執行完后自動釋放return &a; //返回局部變量的地址
}int main()
{//接收func函數的返回值int * p = func();cout<<*p<<endl; //第一次打印正確的數字10,因為編譯器做了保留cout<<*p<<endl; //第2次打印出現亂碼
}
?堆區開辟
?//在堆區開辟數據湖
#include<iostream>
using namespace std;int* func()
{//利用new開辟堆區int *p = new int(10); //指針變量放在棧區,數據放在堆區return p; //返回局部變量的地址
}int main()
{//接收func函數的返回值int * p = func();cout<<*p<<endl; //第一次打印正確的數字10,因為編譯器做了保留cout<<*p<<endl; //第2次打還是10
}
new操作符
C++中利用new操作符在堆區開辟數據湖,堆區開辟的數據,由程序員手動開辟,手動釋放,釋放利用delete
語法:new 數據類型
利用new創建的數據,會返回該數據對應的類型的指針
#include<iostream>
using namespace std;//new的基本語法
int* func()
{//在堆區創建整型數據//new返回是 該數據類型的指針int *p = new int(10); return p;
}void test01()
{int *p = func(); cout << *p <<endl; //如果要釋放,利用delete關鍵字delete p;cout << *p <<endl; //再打印時就打印不出來了
}//在堆區利用new開辟數組
void test02()
{int * arr = new int[10];for(int i=0;i<10;i++){arr[i] = i + 100; //給10個元素賦值}for(int i=0;i<10;i++){cout << arr[i] <<endl; //打印數組中的值}//如果要釋放,利用delete關鍵字delete[] arr; //釋放數組要加[]才可以
}
int main()
{//接收func函數的返回值int * p = func();cout<<*p<<endl; //第一次打印正確的數字10,因為編譯器做了保留cout<<*p<<endl; //第2次打還是10
}?
?