龙炎辉
一代宗师

[IT业界] C语言中内存分布及程序运行加载过程

-->

一个程序内存分配:

下图是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函数 直接内存映射


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

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

参考

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

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

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


#1楼
发帖时间:2016-09-10 02:54:48   |   回复数:1
911degrees
隐世仙人♂
非常感谢,谢谢分享
2016-9-10 #2楼
游客组