zoukankan      html  css  js  c++  java
  • 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
    ";
    10 char g_buffer[20];
    11 
    12 inline void disp_addr(char * p,int addr)
    13 {
    14     printf("Name :%s  Address :%0x
    ",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
    ",buffer1);
    24     free(buffer1);
    25 }
    26 
    27 int main()
    28 {
    29     int i=0;
    30 
    31     //以十六进制显示
    32     printf("Addr etext :%p
    ",&etext);
    33     printf("Addr edata :%p
    ",&edata);
    34     printf("Addr end   :%p
    ",&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

  • 相关阅读:
    1509 加长棒
    51Nod 1158 全是1的最大子矩阵
    P2953 [USACO09OPEN]牛的数字游戏Cow Digit Game
    P3384 【模板】树链剖分
    北京集训DAY3
    北京集训DAY2
    北京集训DAY1
    51Nod 1422 沙拉酱前缀 二分查找
    51Nod 1109 01组成的N的倍数
    51Nod 1043 幸运号码 数位DP
  • 原文地址:https://www.cnblogs.com/wunaozai/p/3636771.html
Copyright © 2011-2022 走看看