Linux 堆、栈

来源:互联网 发布:平面设计需要什么软件 编辑:程序博客网 时间:2024/06/18 05:59

        一个计算机应用程序在内存中可以分成两个部分:存放代码的代码段和存放数据的数据段。代码段存放用户编写的代码;数据段可以分成堆和栈。堆和栈只有在程序运行时才会存在。

       在Liunx系统中,数据段又增加了全局初始化数据区(initialized datasegment/data segment),包含程序中明确被初始化的全局变量、静态变量(包含全局和局部静态变量),以及常量(例如字符串)。

       下面的声明会存放在全局初始化数据区:

int max_size=2048;   //定义在所有函数之外static int buff_size=1024;   //定义在任何地方

       max_size是一个全局静态变量,如果定义在某个函数内,称局部静态变量;int buff_size在定义前面加了一个static修饰符,表示此变量仅能在当前文件中使用。

       未初始化数据区(uninitialized data segment),也称做BSS,存放全局未初始化变量。在Linux系统中,BBS存放的数据在开始执行之前被内核初始化为0或者空指针NULL。

       1、栈

       栈是一个由编译器分配释放的区域,用来存放函数的参数、局部变量等。操作方式类似于数据结构中的栈。当调用函数时,被调用函数的参数和返回值被存储在当前程序的栈区,之后被调用函数再为自身变量以及临时变量在栈区上分配空间。当函数调用返回时,在栈区内的函数返回值,自动变量和临时变量等会被释放。这就是为什么C语言函数参数如果不是指针的话,用户无法得到被修改的参数结果的原因。

       函数的调用和栈的使用方式保证了不同函数内部定义相同名称变量不会被混淆。栈的管理方式是FILO(First In Last Out),即先进后出,栈内的数据是在一个方向管理的,先到达的数据最后被读出来。

       2、堆

       堆(heap)一般位于BSS和栈之间,用来动态分配内存。这段区域由程序员管理,程序员利用操作系统提供的分配和释放函数使用堆区的内存。如果程序员在堆上分配了一块内存,却没有释放,在目前主流的操作系统上,退出时会被操作系统释放。但是这并不是一个好习惯,因为堆中的内存不是无限的,过多地分配会导致堆内存溢出、程序异常,甚至崩溃。

       堆的管理与栈不同,操作系统在堆空间中维护一个链表,每次程序员从堆中分配内存的时候,操作系统会从堆中扫描未使用的空间,当空间的大小符合申请空间时,就会把此空间返回给程序员,同时会把申请的空间加入链表;当释放一块内存空间时,操作系统会从堆的链表中删除指定的节点,并且把释放的空间返回未用空间。

       一个C程序运行时的内存分配情况如下:

//test.cint g_var_a=0;       //存放在全局已初始化数据区char g_var_b;        //存放在BBS区(未初始化全局变量)int main(){int var_a;                    //存放在栈区char var_star[]="string1";    //存放在栈区char *p_str1,*p_str2;         //存放在栈区char *p_str3="string2";       //存放在已初始化数据区,ptr_str3存放在栈区static int var_b=100;         //全局静态数据,存放在已初始化区p_str1=(char*)malloc(1024);   //从堆区分配1024B内存p_str2=(char*)malloc(2048);   //从堆区分配2048B内存free(p_str1);free(p_str2);return 0;}


0 0