Linux进程的虚拟内存区域分为:代码区、只读常量区、全局区、BSS段、堆区、栈区
代码区:存储功能代码,函数名所在的区域
只读常量区:存放字符串常量,以及const修饰的全局变量
全局区/数据区:存放已经初始化的全局变量和已经初始化用static修饰的局部变量
BSS段:存放没有初始化的全局变量和未初始化静态局部变量,该区域会在main函数执行前进行自动清零
堆区:使用malloc/new free/delete函数处理的内存,该区域的内存需要程序员手动申请和释放
栈区:存放局部变量(包括函数的形参),const修饰的局部变量以及块变量,该区域的内存由操作系统负责分配和回收,程序员尽管放心使用
注意:栈区和堆区之间并没有严格分割线,可以进行微调,并且堆区分配一般从低地址到高地址分配,而栈区分配一般从高地址到低地址分配
可以通过以下代码来验证以上Linux进程的虚拟内存区域划分
//进程中内存区域的划分
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int i1 = ; //全局区
int i2 = ; //全局区
int i3; //BSS段
const int i4 = ;//只读常量区 void fn(int i5) //栈区
{
int i6 = ;//栈区
static int i7 = ;//全局区
const int i8 = ; //栈区
int* p1 = (int*)malloc(sizeof(int));//堆区
int* p2 = (int*)malloc(sizeof(int));//堆区
char* str = "good";//只读常量区
char strs[] = "good";//栈区 printf("只读常量区:&i4 = %p\n",&i4);
printf("只读常量去:str = %p\n",str); printf("---------------------\n");
printf("全局区:&i1 = %p\n",&i1);
printf("全局区:&i2 = %p\n",&i2);
printf("全局区:&i7 = %p\n",&i7); printf("---------------------\n");
printf("BSS段:&i3 = %p\n",&i3); printf("---------------------\n");
printf("堆区:p1 = %p\n",p1);
printf("堆区:p2 = %p\n",p2); printf("---------------------\n");
printf("栈区:&i5 = %p\n",&i5);
printf("栈区:&i6 = %p\n",&i6);
printf("栈区:&i8 = %p\n",&i8);
printf("栈区:strs = %p\n",strs);
} int main(void)
{
printf("代码区:fn = %p\n",fn); printf("-----------------------\n");
fn();
return ;
}
执行结果如下:
代码区:fn = 0x40062d
-----------------------
只读常量区:&i4 = 0x400884
只读常量去:str = 0x400888
---------------------
全局区:&i1 = 0x601058
全局区:&i2 = 0x60105c
全局区:&i7 = 0x601060
---------------------
BSS段:&i3 = 0x601068
---------------------
堆区:p1 = 0x1d9b010
堆区:p2 = 0x1d9b030
---------------------
栈区:&i5 = 0x7ffd409525ec
栈区:&i6 = 0x7ffd409525f0
栈区:&i8 = 0x7ffd409525f4
栈区:strs = 0x7ffd40952610