C++学习(5)—— 内存的分区模型
C++程序在执行时,将内存大方向划分为4个区域
- 代码区:存放函数体的二进制代码,由操作系统进行管理的
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数的参数值、局部变量等
- 堆区:由程序员分配和释放。若程序员不释放,程序结束时由操作系统回收
内存四区意义:
- 不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
1.程序运行前
在程序编译后,生成了.exe可执行程序,未执行该程序前分为两个区域
代码区:
-
存放CPU执行的机器指令
-
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
-
代码区是只读的,使其只读的原因是防止程序意外修改它的指令
全局区:
-
全局变量和静态变量存放在此
-
全局区还包含了常量区,字符串常量和其他常量也存放在此
-
该区域的数据在程序结束后由操作系统释放
#include<iostream> using namespace std; //创建全局变量 int g_a = 10; int g_b = 10; //const修饰的全局常量 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; //静态变量 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)&"helloworld" << endl; //const修饰的全局变量 cout << "全局常量c_g_a的地址为:" << (int)&c_g_a << endl; cout << "全局常量c_g_b的地址为:" << (int)&c_g_b << endl; //const修饰的局部变量 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; return 0; }
总结:
- C++中在程序运行前分为全局区和代码区
- 代码区特点是共享和只读
- 全局区中存放全局变量、静态变量、常量
- 常量区中存放const修饰的全局常量和字符串常量
2. 程序运行后
栈区:
-
由编译器自动分配释放,存放函数的参数值,局部变量等
-
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
- 局部变量存放在栈区,栈区的数据在函数执行完成后自动释放
#include<iostream> using namespace std; //栈区数据的注意事项 —— 不要返回局部变量的地址 //栈区数据由编译器管理开辟和释放 int* func(){ int a = 10; return &a; } int main(){ int *p = func(); cout << *p << endl; return 0; }
堆区:
-
由程序员分配释放,若程序员不释放,程序结束时由操作系统回收
-
在C++中主要利用new在堆区开辟内存
#include<iostream> using namespace std; int* func(){ //利用new关键字可以将数据开辟到堆区 //指针的本质也是局部变量,放在栈上,指针保存(指向)的数据是放在堆区 int * p = new int (10); return p; } int main(){ //在堆区开辟数据 int *p = func(); cout << *p << endl; return 0; }
3. new操作符
-
C++中利用new操作符在堆区开辟数据
-
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete
-
语法:
new 数据类型 -
利用new创建的数据,会返回该数据对应的类型的指针
#include<iostream> using namespace std; //1.new的基本语法 int * func(){ //在堆区创建整型数据 //new返回的是该数据类型的指针 int *p = new int(10); return p; } void test01(){ int *p = func(); cout << *p << endl; delete p; cout << *p << endl; } void test02(){ //创建10整型数据的数组,在堆区 int *arr = new int[10]; for(int i=0;i<10;i++){ arr[i] = i+100; } foe(int i=0;i<10;i++){ cout <<arr[i]<<endl; } //释放数组时加中括号 delete[] arr; } int main(){ //在堆区开辟数据 test01(); return 0; }
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

浙公网安备 33010602011771号