新浪微博 登陆  注册   设为首页 加入收藏

学PHP >> UNIX/LINUX >> C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)

查看次数11739 发表时间2014-06-21 18:04:30

C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)BSS段:(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属...

C语言中内存分布及程序运行中(BSS段、数据段、代码段、堆栈)


BSS段:(bss segment)通常是指用来存放程序中未初始化全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

数据段 :数据段(data segment)通常是指用来存放程序中 已初始化  全局变量 的一块内存区域。数据段属于静态内存分配。
代码段: 代码段(code segment/text segment)通常是指用来存放 程序执行代码 的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于 只读 , 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些 只读的常数变量 ,例如字符串常量等。程序段为程序代码在内存中的映射.一个程序可以在内存中多有个副本.

堆(heap) :堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)

栈(stack) :栈又称堆栈, 存放程序的 局部变量 (但不包括static声明的变量, static 意味着 在数据段中 存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场储动态内存分配,需要程序员手工分配,手工释放

下图是APUE中的一个典型C内存空间分布图

 例如:

#include

int g1=0, g2=0, g3=0;

int max(int i)
{
    int m1=0,m2,m3=0,*p_max;
    static n1_max=0,n2_max,n3_max=0;
     p_max = (int*)malloc(10);
    printf("打印max程序地址 ");
    printf("in max: 0xx ",max);
    printf("打印max传入参数地址 ");
    printf("in max: 0xx ",&i);
    printf("打印max函数中静态变量地址 ");
    printf("0xx ",&n1_max); //打印各本地变量的内存地址
    printf("0xx ",&n2_max);
    printf("0xx ",&n3_max);
    printf("打印max函数中局部变量地址 ");
    printf("0xx ",&m1); //打印各本地变量的内存地址
    printf("0xx ",&m2);
    printf("0xx ",&m3);
    printf("打印max函数中malloc分配地址 ");
    printf("0xx ",p_max); //打印各本地变量的内存地址

    if(i) return 1;
    else return 0;
}

int main(int argc, char **argv)
{
    static int s1=0, s2, s3=0;
    int v1=0, v2, v3=0;
    int *p;   
    p = (int*)malloc(10);

    printf("打印各全局变量(已初始化)的内存地址 ");
    printf("0xx ",&g1); //打印各全局变量的内存地址
    printf("0xx ",&g2);
    printf("0xx ",&g3);
    printf("====================== ");
    printf("打印程序初始程序main地址 ");
    printf("main: 0xx ", main);
    printf("打印主参地址 ");
    printf("argv: 0xx ",argv);
    printf("打印各静态变量的内存地址 ");
    printf("0xx ",&s1); //打印各静态变量的内存地址
    printf("0xx ",&s2);
    printf("0xx ",&s3);
    printf("打印各局部变量的内存地址 ");
    printf("0xx ",&v1); //打印各本地变量的内存地址
    printf("0xx ",&v2);
    printf("0xx ",&v3);
    printf("打印malloc分配的堆地址 ");
    printf("malloc: 0xx ",p);
    printf("====================== ");
    max(v1);
    printf("====================== ");
    printf("打印子函数起始地址 ");
    printf("max: 0xx ",max);
    return 0;
}

 打印结果:

可以大致查看整个程序在内存中的分配情况:
可以看出,传入的参数,局部变量,都是在栈顶分布,随着子函数的增多而向下增长.
函数的调用地址(函数运行代码),全局变量,静态变量都是在分配内存的低部存在,而malloc分配的堆则存在于这些内存之上,并向上生长.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在操作系统中,一个进程就是处于执行期的程序(当然包括系统资源),实际上正在执行的程序代码的活标本。那么进程的逻辑地址空间是如何划分的呢?

引用:

 

图1做了简单的说明(Linux系统下的)


C语言中内存分布及程序运行中

左边的是UNIX/LINUX系统的执行文件,右边是对应进程逻辑地址空间的划分情况。



首先是堆栈区(stack),堆栈是由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。栈的申请是由系统自动分配,如在函数内部申请一个局部变量 int h,同时判别所申请空间是否小于栈的剩余空间,如若小于的话,在堆栈中为其开辟空间,为程序提供内存,否则将报异常提示栈溢出。   学PHP)    


  相关推荐




  发表评论
昵称:
(不超过20个字符或10个汉字)
内容: