C++内存布局
一、文字介绍
1.内核态空间:3-4G高地址
在典型的 32 位 Linux 系统中,虚拟地址空间通常按以下方式划分:
0x00000000 到 0xBFFFFFFF:用户态地址空间(低地址0-3GB,共3GB),供用户进程使用。
0xC0000000 到 0xFFFFFFFF:内核态地址空间(高地址3-4GB,共1GB),供操作系统内核和内核模块使用。
2.用户态空间:0-3G低地址
(1)栈区
1.栈区:存储局部变量和函数调用的相关信息,栈的特点是自动分配和释放,由操作系统管理。
2.栈的生长方向:向下生长,即由高地址向低地址生长,通常为0x7ff
(2)堆区
1.堆区:堆区用于动态分配的内存(new、malloc),由程序员分配。
2.堆的生长方向:向上生长,由低地址向高地址生长,堆区与栈区没有明确的界限,通常为0x5
(3)全局/静态区
1.全局/静态区:读写段(数据段),存放全局变量、静态变量。
2.分为:①已初始化数据段.data ②未初始化数据段.bss
(4)文字常量区
文字常量区:只读段.rodata,存放程序中直接使用的常量,如 字符串常量、整数常量、浮点数常量
(5)程序代码区
程序代码区:只读段,存放函数体的二进制代码
二、图片介绍


三、代码介绍
(1)堆比栈的地址更低
(2)堆区是动态分配的,地址不一定连续
(3)全局变量在堆之下
(4)静态变量 和 全局变量是混合存放的。先定义的在低地址。
//memory_layout.cpp
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;
int global_num = 1;
int main()
{
int num = 1; //栈变量
cout << "栈变量1的地址 :" << &num << endl; //输出栈变量的地址:0x7ffc2050a440
int num2 = 2; //栈变量
cout << "栈变量2的地址 :" << &num2 << endl; //输出栈变量的地址:0x7ffc2050a444
int *p = new int(1); //堆变量
cout << "堆变量的地址 :" << p << endl; //输出堆变量的地址:0x56bb74428280
int *p2 = new int(2); //堆变量
cout << "堆变量2的地址 :" << p2 << endl; //输出堆变量的地址:0x56bb744282a0
//对比发现,堆变量的地址比栈变量低
//即,堆变量是低地址,栈变量是高地址
cout << "全局变量的地址:" << &global_num << endl; //0x56bb73306010
static int static_num = 1;
cout << "静态变量的地址:" << &static_num << endl; //0x56bb73306014
//对比可以发现,全局变量和静态变量是混合存放的。略低于堆区
const char * pstr = "hello";
cout << pstr << endl; //hello cout会默认重载char *
printf("文字常量区的地址:%p\n", pstr); //0x56012fd1ddab
cout << "文字常量区的地址:"<< static_cast<void *>(const_cast<char*>(pstr))<<endl;
//发现文字常量区,比全局静态区的地址更低
printf("main函数的地址:%p\n",&main);
//发现程序代码段,比文字常量区更低
return 0;
}


1609

被折叠的 条评论
为什么被折叠?



