美文网首页IT人程序员的日常
C语言中内存分布及程序运行加载过程

C语言中内存分布及程序运行加载过程

作者: 小王同学加油 | 来源:发表于2016-04-23 08:50 被阅读520次

    一个程序内存分配:
    下图是APUE中的一个典型C内存空间分布图(虚拟内存)


    C语言中内存分布及程序运行加载过程

    例如:

    include

    int g1=0, g2=0, g3=0;
    int max(int i)
    {
    int m1=0,m2,m3=0,p_max;
    static n1_max=0,n2_max,n3_max=0;
    p_max = (int
    )malloc(10);
    printf("打印max程序地址\n");
    printf("in max: 0xx\n\n",max);
    printf("打印max传入参数地址\n");
    printf("in max: 0xx\n\n",&i);
    printf("打印max函数中静态变量地址\n");
    printf("0xx\n",&n1_max); //打印各本地变量的内存地址
    printf("0xx\n",&n2_max);
    printf("0xx\n\n",&n3_max);
    printf("打印max函数中局部变量地址\n");
    printf("0xx\n",&m1); //打印各本地变量的内存地址
    printf("0xx\n",&m2);
    printf("0xx\n\n",&m3);
    printf("打印max函数中malloc分配地址\n");
    printf("0xx\n\n",p_max); //打印各本地变量的内存地址
    if(i) return 1;
    else return 0;
    }
    int main(int argc, char **argv)
    {
    static int s1=0, s2, s3=0;
    int v1=0, v2, v3=0;
    int p;
    p = (int
    )malloc(10);
    printf("打印各全局变量(已初始化)的内存地址\n");
    printf("0xx\n",&g1); //打印各全局变量的内存地址
    printf("0xx\n",&g2);
    printf("0xx\n\n",&g3);
    printf("======================\n");
    printf("打印程序初始程序main地址\n");
    printf("main: 0xx\n\n", main);
    printf("打印主参地址\n");
    printf("argv: 0xx\n\n",argv);
    printf("打印各静态变量的内存地址\n");
    printf("0xx\n",&s1); //打印各静态变量的内存地址
    printf("0xx\n",&s2);
    printf("0xx\n\n",&s3);
    printf("打印各局部变量的内存地址\n");
    printf("0xx\n",&v1); //打印各本地变量的内存地址
    printf("0xx\n",&v2);
    printf("0xx\n\n",&v3);
    printf("打印malloc分配的堆地址\n");
    printf("malloc: 0xx\n\n",p);
    printf("======================\n");
    max(v1);
    printf("======================\n");
    printf("打印子函数起始地址\n");
    printf("max: 0xx\n\n",max);
    return 0;
    }

    打印结果:

    C语言中内存分布及程序运行加载过程
    可以大致查看整个程序在内存中的分配情况:
    可以看出,传入的参数,局部变量,都是在栈顶分布,
    随着子函数的增多而向下增长.
    函数的调用地址(函数运行代码)(高地址)
    而malloc分配的堆则存在于这些内存之上,并向上生长
    全局变量,静态变量都是在分配内存的低部存在(低地址)
    程序如何装载的
    1 编译:
    C语言中内存分布及程序运行加载过程
    2 编译结果:
    C语言中内存分布及程序运行加载过程
    file a.out 查看文件类型
    a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xd66ac36636c4fcfcbe395efb6bbd38c053e1c6c7, not stripped

    ELF目标文件格式的最前端是ELF****文件头(****ELF Header****)
    包含了描述整个文件的基本属性,如ELF版本、目标机器型号、程序入口地址
    3 加载:

    C语言中内存分布及程序运行加载过程
    图1做了简单的说明(Linux系统下的)
    C语言中内存分布及程序运行加载过程
    左边的是UNIX/LINUX系统的执行文件,右边是对应进程逻辑地址空间的划分情况。
    我理解就是类似mmap函数 直接内存映射
    1 ELF****文件头 指定加载入口地址
    2 加载 代码段 数据段 其他部分
    参考
    1 Linux内核如何装载和启动一个可执行程序
    http://www.cnblogs.com/bushifudongjing/p/5361805.html
    2 <程序员的自我修养—链接、装载与库.pdf>

    相关文章

      网友评论

        本文标题:C语言中内存分布及程序运行加载过程

        本文链接:https://www.haomeiwen.com/subject/mhixrttx.html