C程序-进程内存结构分析

  

  1. 每个进程都运行在自己私有的内存空间中(即虚拟地址空间)。在32位系统中,4GB的进程地址东健被分为用户空间和内核空间两个部分。用户空间占据着0~3GB(用16进制表示为0xC0000000),而内核空间的范围是3GB~4GB。对于一个进程而言,都会涉及3种不同的数据段,分别是代码段、数据段和堆栈段。

  代码段:用于保存可执行文件的操作指令和程序定义的常量。为了防止代码在运行的时候被其他进程修改,代码段将只允许读取,不能进行修改。多进程能够共享相同的代码段,即当程序被多次执行时,运行的相同程序将共享代码段。

  数据段:其位置紧接着代码段,分为初始化数据段和未初始化数据段(也称为BSS段)。初始化代码段用于存放已经初始化的全局变量和程序的静态变量,而未初始化数据段用于保存未初始化的全局变量。

  堆栈段:堆栈段的堆用于存放进程中动态分配的内存地址。例如,在C语言中使用malloc函数、在C++中使用new函数分配的内存空间都将在堆中分配。当使用free函数或delete函数释放内存时,分配的内存将从堆中删除。栈用于保存程序中创建的临时变量。函数调用时,传递的参数也将被保存在栈中。在函数调用结束后,其返回值也将保存在栈中。栈具有先进先出的特点,适用于保存和恢复现场。可以将栈看作用于存放临时数据、进行数据交换的内存区域。栈的大小受操作系统的限制,因此从栈中获得的空间大小有限,而堆的大小只是受限于虚拟内存空间,因此使用堆可以获得较大的内存空间。堆的位置与数据段相邻。

  2. 代码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 
 6 int etext,edata,end;//
 7 
 8 //g_pstr和g_buffer都为全局变量,只是一个初始化,一个未初始化
 9 char *g_pstr="Global string\n";
10 char g_buffer[20];
11 
12 inline void disp_addr(char * p,int addr)
13 {
14     printf("Name :%s  Address :%0x\n",p,addr);
15 }
16 
17 void disp_var(char* p)
18 {
19     char *buffer1;
20     disp_addr("buffer1 address:",(int)(&buffer1));
21     buffer1=(char*)malloc(strlen(p)+1);
22     strcpy(buffer1,p);
23     printf("buffer1 : %s\n",buffer1);
24     free(buffer1);
25 }
26 
27 int main()
28 {
29     int i=0;
30 
31     //以十六进制显示
32     printf("Addr etext :%p\n",&etext);
33     printf("Addr edata :%p\n",&edata);
34     printf("Addr end   :%p\n",&end);
35 
36     //显示各个函数和变量地址
37     disp_addr("  function main()  :",(int)(main));
38     disp_addr("function disp_var():",(int)(disp_var));
39     disp_addr("   g_pstr address  :",(int)(&g_pstr));
40     disp_addr(" g_buffer address  :",(int)(&g_buffer));
41     disp_addr("   i address       :",(int)(&i));
42 
43     disp_var(g_pstr);
44     return 0;
45 }

 

  3. 运行结果

Addr etext :0x8049954
Addr edata :0x8049958
Addr end   :0x8049950
Name :  function main()  :,Address :804850c
Name :function disp_var():,Address :80484a7
Name :   g_pstr address  :,Address :8049930
Name : g_buffer address  :,Address :804993c
Name :   i address       :,Address :bf8583ec
Name :buffer1 address:,Address :bf8583bc
buffer1 : Global string

 

  4. 图示

 

  5.用户空间到0xC0000000-0xBFB18CAC = 栈的大小  

   在VC或VS中好像是使用 #pragma comment(linker, "/STACK:1024000000,1024000000")

   至于linux 下就不太清楚了

 

 

  出处:http://www.cnblogs.com/wunaozai/p/3636771.html

posted @ 2014-03-31 20:35  无脑仔的小明  阅读(2218)  评论(0编辑  收藏  举报