Linux进程的虚拟内存区域划分

Linux进程的虚拟内存区域分为:代码区、只读常量区、全局区、BSS段、堆区、栈区

代码区:存储功能代码,函数名所在的区域

只读常量区:存放字符串常量,以及const修饰的全局变量

全局区/数据区:存放已经初始化的全局变量和已经初始化用static修饰的局部变量

BSS段:存放没有初始化的全局变量和未初始化静态局部变量,该区域会在main函数执行前进行自动清零

堆区:使用malloc/new free/delete函数处理的内存,该区域的内存需要程序员手动申请和释放

栈区:存放局部变量(包括函数的形参),const修饰的局部变量以及块变量,该区域的内存由操作系统负责分配和回收,程序员尽管放心使用

注意:栈区和堆区之间并没有严格分割线,可以进行微调,并且堆区分配一般从低地址到高地址分配,而栈区分配一般从高地址到低地址分配

 

可以通过以下代码来验证以上Linux进程的虚拟内存区域划分

//进程中内存区域的划分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int i1 = 10; //全局区
int i2 = 20; //全局区
int i3;     //BSS段
const int i4 = 40;//只读常量区

void fn(int i5) //栈区
{
    int i6 = 60;//栈区
    static int i7 = 70;//全局区
    const int i8 = 80; //栈区
    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(10);
    return 0;
}

执行结果如下:

代码区: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

posted @ 2017-05-19 16:54  大海中的一粒沙  阅读(3229)  评论(0编辑  收藏  举报