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/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。有需要沟通的,可以站内私信,文章留言,或者关注“无脑仔的小明”公众号私信我。一定尽力回答。 |