前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言中内存分布及程序运行加载过程

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

作者头像
程序员小王
发布2018-04-13 10:54:36
2K0
发布2018-04-13 10:54:36
举报
文章被收录于专栏:架构说

一个程序内存分配:

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

例如:

代码语言:javascript
复制
#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;
}

打印结果:

可以大致查看整个程序在内存中的分配情况:

可以看出,传入的参数,局部变量,都是在栈顶分布,

随着子函数的增多而向下增长. 函数的调用地址(函数运行代码)(高地址)

而malloc分配的堆则存在于这些内存之上,并向上生长

全局变量,静态变量都是在分配内存的低部存在(低地址)

程序如何装载的

1 编译:

2 编译结果:

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 加载:

图1做了简单的说明(Linux系统下的)

左边的是UNIX/LINUX系统的执行文件,右边是对应进程逻辑地址空间的划分情况。

我理解就是类似mmap函数 直接内存映射

1 ELF文件头 指定加载入口地址

2 加载 代码段 数据段 其他部分

参考

1 Linux内核如何装载和启动一个可执行程序

http://www.cnblogs.com/bushifudongjing/p/5361805.html

2 <程序员的自我修养—链接、装载与库.pdf>

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档