文章目录
- 内存四区
- 1.程序运行前
- 1.1 代码区
- 2.1 全局区
- 2.2 示例
- 2.程序运行后
- 1.1 栈区
- 1.2 堆区
内存四区
1.程序运行前
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域。该区域的数据在程序结束后由操作系统释放.
1.1 代码区
- 存放 CPU 执行的机器指令
- 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
- 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
2.1 全局区
- 全局变量和静态变量存放在此.
- 全局区还包含了常量区, 字符串常量和其他常量也存放在此.
2.2 示例
#include <iostream>
#include <vector>
#include <string>
#include <cstdint> // 包含 uintptr_t 的头文件
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地址为: " << (uintptr_t)&a << endl;cout << "局部变量b地址为: " << (uintptr_t)&b << endl;cout << "全局变量g_a地址为: " << (uintptr_t)&g_a << endl;cout << "全局变量g_b地址为: " << (uintptr_t)&g_b << endl;// 静态变量static int s_a = 10;static int s_b = 10;cout << "静态变量s_a地址为: " << (uintptr_t)&s_a << endl;cout << "静态变量s_b地址为: " << (uintptr_t)&s_b << endl;cout << "字符串常量地址为: " << (uintptr_t)"hello world" << endl;cout << "字符串常量地址为: " << (uintptr_t)"hello world1" << endl;cout << "全局常量c_g_a地址为: " << (uintptr_t)&c_g_a << endl;cout << "全局常量c_g_b地址为: " << (uintptr_t)&c_g_b << endl;const int c_l_a = 10;const int c_l_b = 10;cout << "局部常量c_l_a地址为: " << (uintptr_t)&c_l_a << endl;cout << "局部常量c_l_b地址为: " << (uintptr_t)&c_l_b << endl;// system("pause");return 0;
}
局部变量a地址为: 140729157773912
局部变量b地址为: 140729157773916
全局变量g_a地址为: 93857217380368
全局变量g_b地址为: 93857217380372
静态变量s_a地址为: 93857217380376
静态变量s_b地址为: 93857217380380
字符串常量地址为: 93857215278679
字符串常量地址为: 93857215278691
全局常量c_g_a地址为: 93857215278472
全局常量c_g_b地址为: 93857215278476
局部常量c_l_a地址为: 140729157773920
局部常量c_l_b地址为: 140729157773924
2.程序运行后
1.1 栈区
- 由编译器自动分配释放, 存放函数的参数值,局部变量等
- 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
int * func()
{int a = 10;//局部变量,存放在栈区,栈区的数据在函数执行完后自动释放return &a;//返回局部变量的地址
}int main() {//接受func函数的返回值int *p = func();cout << *p << endl;//第一次可以打印正确是因为编译器做了保留cout << *p << endl;//第二次就不保留了system("pause");return 0;
}
1.2 堆区
- 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收
- 在C++中主要利用new在堆区开辟内存,释放用delete。
int* func()
{//指针本质上是局部变量,放在栈上,指针保存的数据放在堆区int* a = new int(10);//利用new关键字将数据开辟到堆区return a;
}int main() {int *p = func();cout << *p << endl;cout << *p << endl;system("pause");return 0;
}