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

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

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

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

  2. 代码

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> int etext,edata,end;// //g_pstr和g_buffer都为全局变量,只是一个初始化,一个未初始化
char *g_pstr="Global string\n";
char g_buffer[]; inline void disp_addr(char * p,int addr)
{
printf("Name :%s Address :%0x\n",p,addr);
} void disp_var(char* p)
{
char *buffer1;
disp_addr("buffer1 address:",(int)(&buffer1));
buffer1=(char*)malloc(strlen(p)+);
strcpy(buffer1,p);
printf("buffer1 : %s\n",buffer1);
free(buffer1);
} int main()
{
int i=; //以十六进制显示
printf("Addr etext :%p\n",&etext);
printf("Addr edata :%p\n",&edata);
printf("Addr end :%p\n",&end); //显示各个函数和变量地址
disp_addr(" function main() :",(int)(main));
disp_addr("function disp_var():",(int)(disp_var));
disp_addr(" g_pstr address :",(int)(&g_pstr));
disp_addr(" g_buffer address :",(int)(&g_buffer));
disp_addr(" i address :",(int)(&i)); disp_var(g_pstr);
return ;
}

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

C程序-进程内存结构分析的更多相关文章

  1. Linux系统下输出某进程内存占用信息的c程序实现

    在实际工作中有时需要程序打印出某个进程的内存占用情况以作参考, 下面介绍一种通过Linux下的伪文件系统/proc 计算某进程内存占用的程序实现方法. 首先, 为什么会有所谓的 伪文件 呢. Linu ...

  2. 如何优化cocos2d程序的内存使用和程序大小

    在我完成第一个游戏项目的时候,我深切地意识到"使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰".而我刚开始接触cocos2d的时候,社区里面的人 ...

  3. 如何优化cocos2d程序的内存使用和程序大小:第一部分

    译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...

  4. java\c程序的内存分配

    JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...

  5. Linux C进程内存布局

    当程序文件运行为进程时,进程在内存中获得空间.这个空间是进程自己的内存空间.每个进程空间按照如下方式分为不同区域: 进程内存空间布局图 text:代码段.存放的是程序的全部代码(指令),来源于二进制可 ...

  6. 程序的内存分配 C\C++

    原文:http://blog.csdn.net/oohaha_123/article/details/24460425 程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区( ...

  7. Linux C 程序 进程控制(17)

    进程控制 1.进程概述现代操作系统的特点在于程序的并行执行.Linux是一个多用户多任务的操作系统.ps .pstree 查看进程进程除了进程id外还有一些其他标识信息,可以通过相应的函数获得.// ...

  8. C程序的内存分配

    一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...

  9. 如何优化cocos2d程序的内存使用和程序大小:第一部分_(转)

    译者: 在我完成第一个游戏项目的时候,我深切地意识到“使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰”.而我刚开始接触cocos2d的时候,社区里面的人们讨论了一个 ...

随机推荐

  1. linux下apache的使用

    Linux安装配置apache http://www.cnblogs.com/fly1988happy/archive/2011/12/14/2288064.html 1.获取软件: http://h ...

  2. php之快速入门学习-1

    貌似和JSP差不多! PHP 脚本可以放在文档中的任何位置. PHP 脚本以 <?php 开始,以 ?> 结束: <?php// PHP 代码?> PHP 文件的默认文件扩展名 ...

  3. HDU 4902 Nice boat 成段线段树

    操作1 的时候标记deng[rt]表示以下一段数都是与当前节点的值同样 下次操作2时直接对有deng标记的节点gcd更新 (可能还能够更简单) #include <stdio.h> #in ...

  4. Swift高速入门之函数

    函数 看一个函数的样例: func addNumbers( let a:Int,let b:Int)->Int{ return a+b; } 实现两个数相加.函数必须以func开头,后面是函数名 ...

  5. Ubuntu 下iscsi initiator的安装与使用

    Ubuntu下比较方便好用的initiator是open iscsi,这里将要简要介绍它的使用方法: 1.安装: sudo apt-get install open-iscsi 2.chap设置 如果 ...

  6. Ubuntu12.04+OpenERP6.1更改HTTP端口号为80

    在Ubuntu12.04中安装好OpenERP6.1以后,默认的端口号为8069,如果我们想改变为默认的80端口,可以通过如下方式处理. 1.首先通过iptables进行端口映射转换:sudo ipt ...

  7. SQL Server 2012 “阻止保存要求又一次创建表”的更改问题的设置方法

    我们在用SQL Server 2012 建完表后,插入或改动随意列时,提示:当用户在在SQL Server 2012企业管理器中更改表结构时.必需要先删除原来的表.然后又一次创建新表,才干完毕表的更改 ...

  8. windows登陆密码破解方法之一

    网上的一些人让别人进入命令提示符安全模式,我比较奇怪如果没有密码怎么进去?能进去干嘛还要进去? 本笨方法的原理主要是利用登陆界面的一些程序入口,把它当成后门来使用,比如win7登陆界面上除了输密码的地 ...

  9. iOS 封装跑马灯和轮播效果

    代码地址如下:http://www.demodashi.com/demo/14075.html 功能概述和预览 功能描述:WSL_RollView 是基于UICollectionView实现的支持水平 ...

  10. JavaScript实现碰撞检测(分离轴定理)

    概述 分离轴定理是一项用于检测碰撞的算法.其适用范围较广,涵盖检测圆与多边形,多边形与多边形的碰撞:缺点在于无法检测凹多边形的碰撞.本demo使用Js进行算法实现,HTML5 canvas进行渲染. ...