linux 下C程序内存分布
2014-09-26 15:51
176 查看
先问大家个问题,在linux下,对于C源程序到可执行文件的过程大家清楚吗?还有一个可执行文件是怎样运行的?
一 源文件到可执行文件的过程如下:
源程序----预编译中间文件---汇编文件----目标文件-----可执行文件.
我们平常运行程序时,只是在终端下直接收入gcc test -o test 就生成了可执行文件,或者直接输入
gcc test生成a.out可执行文件,其实计算机是做了好几步工作的.底下我们分解下:
第一步 预处理 gcc -E test.c -o test.i //生成预编译处理文件
第二步 编译 gcc -S test.i -o test.s //生成汇编文件
第三步 汇编 gcc -c test.s -o test.o //生成目标文件
第四步 链接 gcc test.o -o test //生成可执行文件
然而当执行一个可执行文件时,系统是怎么做得呢?
当可执行程序执行时,操作系统可执行程序复制到内存当中,将其转化为进程.通常经过以下步骤:
1.内核将程序读入内存,为程序分配内存空间.
2.内核为该进程分配进程标识符,和其他所需资源,
3.把程序放到运行队列中等待执行.
二.进程的内存映像(即C程序内存分配)
如下图所示:
按照内存地址由高到低的顺序
栈: 由编译器自动分配释放管理.
用于函数调用,保存函数的返回地址,函数的参数,函数内部定义的局部变量.
堆 : 需要由程序员分配释放管理,若程序员不释放,程序结束时可能由OS回收。通常在堆中进行动态存储分 配。(建议一定要手动释放,不然会造成内存泄漏)
未被初始化数据段(bbs)
它属于静态存储区,但是该段中的数据没有经过初始化.即存放未初始化的静态变量或全局变量.
数据段
数据段分为读写数据段和只读数据段
读写数据段
已初始化的全局变量或者已初始化的静态变量.
只读数据段
只读全局量和只读局部量(使用const); 程序中使用的常量.
代码段
即二进制代码,代码段是只读的,可被多个进程共享.
三.底下这个程序大家好好看看程序运行结果,对比看看地址的变化,相信你会更加了解在这块
点击(此处)折叠或打开
#include <stdio.h>
#include <malloc.h>
int shengsheng = 250; //全局变量已初始化
int sheng; //全局变量未初始化
main()
{
static int shengdi; //静态变量未初始化
const static int hange = 3; //静态只读局部变量
char *s1 = "abcde";
char *s2 = "abcde";
char s3[] = "abcde";
long int *s4[100];
char *s5 = "abcde";
int a = 5;
int b =6;//a,b在栈上,&a>&b
地址反向增长
int *c,*q;
c=(int *)malloc(4);
q=(int *)malloc(4);
printf("\n stack_&s1=%p stack_&s2=%p stack_&s3=%p stack_&s4=%p\n ", &s1,&s2,&s3,&s4);
printf(" stack_&s5=%p stack_a=%p stack_b=%p\n",&s5,&a,&b);
printf("\n\n stack_s1=%p, stack_s2=%p, stack_s3=%p\n",s1,s2,s3);
printf(" stack_s4=%p, stack_s5=%p \n",s4,s5);
printf("\n global_init_shengsheng=%p const_static_init_hange=%p\n",&shengsheng,&hange);
printf("\nglobal_shengdi=%p heap_c=%p heap_q=%p\n\n",&shengdi,c,q);
printf(" &head_c=%p head_q=%p\n\n",&c,&q);
return 0;
}
大家注意看下地址变化,在对照着上图看看,希望对你有帮助.
一 源文件到可执行文件的过程如下:
源程序----预编译中间文件---汇编文件----目标文件-----可执行文件.
我们平常运行程序时,只是在终端下直接收入gcc test -o test 就生成了可执行文件,或者直接输入
gcc test生成a.out可执行文件,其实计算机是做了好几步工作的.底下我们分解下:
第一步 预处理 gcc -E test.c -o test.i //生成预编译处理文件
第二步 编译 gcc -S test.i -o test.s //生成汇编文件
第三步 汇编 gcc -c test.s -o test.o //生成目标文件
第四步 链接 gcc test.o -o test //生成可执行文件
然而当执行一个可执行文件时,系统是怎么做得呢?
当可执行程序执行时,操作系统可执行程序复制到内存当中,将其转化为进程.通常经过以下步骤:
1.内核将程序读入内存,为程序分配内存空间.
2.内核为该进程分配进程标识符,和其他所需资源,
3.把程序放到运行队列中等待执行.
二.进程的内存映像(即C程序内存分配)
如下图所示:
按照内存地址由高到低的顺序
栈: 由编译器自动分配释放管理.
用于函数调用,保存函数的返回地址,函数的参数,函数内部定义的局部变量.
堆 : 需要由程序员分配释放管理,若程序员不释放,程序结束时可能由OS回收。通常在堆中进行动态存储分 配。(建议一定要手动释放,不然会造成内存泄漏)
未被初始化数据段(bbs)
它属于静态存储区,但是该段中的数据没有经过初始化.即存放未初始化的静态变量或全局变量.
数据段
数据段分为读写数据段和只读数据段
读写数据段
已初始化的全局变量或者已初始化的静态变量.
只读数据段
只读全局量和只读局部量(使用const); 程序中使用的常量.
代码段
即二进制代码,代码段是只读的,可被多个进程共享.
三.底下这个程序大家好好看看程序运行结果,对比看看地址的变化,相信你会更加了解在这块
点击(此处)折叠或打开
#include <stdio.h>
#include <malloc.h>
int shengsheng = 250; //全局变量已初始化
int sheng; //全局变量未初始化
main()
{
static int shengdi; //静态变量未初始化
const static int hange = 3; //静态只读局部变量
char *s1 = "abcde";
char *s2 = "abcde";
char s3[] = "abcde";
long int *s4[100];
char *s5 = "abcde";
int a = 5;
int b =6;//a,b在栈上,&a>&b
地址反向增长
int *c,*q;
c=(int *)malloc(4);
q=(int *)malloc(4);
printf("\n stack_&s1=%p stack_&s2=%p stack_&s3=%p stack_&s4=%p\n ", &s1,&s2,&s3,&s4);
printf(" stack_&s5=%p stack_a=%p stack_b=%p\n",&s5,&a,&b);
printf("\n\n stack_s1=%p, stack_s2=%p, stack_s3=%p\n",s1,s2,s3);
printf(" stack_s4=%p, stack_s5=%p \n",s4,s5);
printf("\n global_init_shengsheng=%p const_static_init_hange=%p\n",&shengsheng,&hange);
printf("\nglobal_shengdi=%p heap_c=%p heap_q=%p\n\n",&shengdi,c,q);
printf(" &head_c=%p head_q=%p\n\n",&c,&q);
return 0;
}
大家注意看下地址变化,在对照着上图看看,希望对你有帮助.
相关文章推荐
- linux及windows程序内存分布
- linux程序调试(一)------内存分布
- 【操作系统】Linux中C程序的内存分布情况
- linux下的程序内存分布 代码段,数据段,BSS段,.rodata段,堆,栈
- 程序在内存中的分布(今天的一个问题)
- valgrind 使用 (linux程序内存检测)
- 应用 Valgrind 发现 Linux 程序的内存问题
- c/c++程序编译后的内存分布
- Linux下程序的内存占用
- Linux 和 Vxworks 的内存分布-区别与联系
- linux下查看运行程序的内存空间
- 可执行程序的内存分布
- C程序可执行文件和运行时的内存分布
- linux里面C程序内存布局
- 把内存当硬盘使,让你的linux程序运转如飞(在linux下用firefox在线写csdn的blog再也不卡了)
- Valgrind 与 Linux 程序的内存问题
- 应用 Valgrind 发现 Linux 程序的内存问题
- 程序的内存分布
- 【转】应用 Valgrind 发现 Linux 程序的内存问题
- 应用 Valgrind 发现 Linux 程序的内存问题