首页 > 代码库 > C程序的存储空间

C程序的存储空间

    参考:《UNIX环境高级编程》第7章 7.6

    C程序一般有下面几部分构成

    正文段:又叫文本段,这是有CPU执行的机器指令部分。通常,正文段是可以共享的,并 且是只读的。

    初始化数据段:通常将此段作为数据段,它包含了程序中需要明确的赋初值的变量,比如函 数外的声明:int cnt = 10;

    非初始化数据段:通常此数据段称为bss(block start symbol),在程序开始执行之前,内核 将此段中的数据初始化为0或空指针。比如函数外声明:int arr[100];

    栈:自动变量以及每次函数调用所需保存的信息都存放在此段中。调用函数其返回地址也保 存在栈中。递归函数每调用一次自身,就是用一个新的栈帧,这样一个函数调

用中的变量集就不会影响另一个函数调用函数的变量。

    堆:通常在堆中进行动态存储分配,由于历史上的惯例,堆位于非初始化数据段和栈之间。


size命令报告正文段、数据段和bss段长度(单位:字节)



测试实例:

#include "apue.h"

void myexit(void)
{
    printf("I am in myexit.\n");
}

int main(void)
{
    printf("I am in main.c\n");

    return 0;
}


把程序改为

#include "apue.h"

void myexit(void)
{
    printf("I am in myexit.\n");
}

int main(void)
{
    printf("I am in main.c\n");

    return 0;
}

结论:1、未初始化的全局变量保存在bss


当把程序改为

#include "apue.h"

void myexit(void)
{
    printf("I am in myexit.\n");
}
int a = 1;
int main(void)
{
    printf("I am in main.c\n");

    return 0;
}

结论:2、初始化的全局变量保存在数据段中


当把程序改为

#include "apue.h"

void myexit(void)
{
    printf("I am in myexit.\n");
}
static int a;
int main(void)
{
    printf("I am in main.c\n");

    return 0;
}

结论:3、未初始化的静态变量保存在bss段中


当把程序改为

#include "apue.h"

void myexit(void)
{
    printf("I am in myexit.\n");
}
static int a = 1;
int main(void)
{
    printf("I am in main.c\n");

    return 0;
}

结论:4、初始化的静态变量保存在数据段中


当把程序改为

#include "apue.h"

void myexit(void)
{
    int a;
    printf("I am in myexit.\n");
}

int main(void)
{
    printf("I am in main.c\n");

    return 0;
}

结论:5、函数内部声明的局部变量保存在堆栈段中


    未初始化数据段的内容并不存放在磁盘上的程序文件中,因为内核在程序开始运行前将它们都设置为0,。需要存放在程序文件中的段只有正文段和初始化数据段。

    Linux中的size命令输出不包括stack和heap的部分,只包括文本段(test)、代码段(data)和未初始化数据段(bss)三部分。


小结:

1、未初始化的全局变量保存在bss

2、初始化的全局变量保存在数据段中

3、未初始化的静态变量保存在bss段中

4、初始化的静态变量保存在数据段中

5、函数内部声明的局部变量保存在堆栈段中

6、未初始化的静态变量(包括全局和布局变量)保存在bss

7、初始化的静态变量(包括全局和局部变量)保存在data

C程序的存储空间