您的位置:首页 > 理论基础

计算机中堆栈的概念

2015-12-29 23:52 302 查看
原文:计算机中堆栈的概念

在英文中,我们管栈称为stack,管堆称为heap。在计算机中,堆栈是两种不同的数据结构,但堆栈均为一种按序排列的数据结构。只能在一端对数据项进行插入和删除。其中的关键是,堆,的排列顺序是随意的,而栈,排列顺序是先进后出(First In Last Out)。

堆:为编译器自动的分配与释放,用来存放函数的参数值与局部变量。其操作方式类似于数据结构中的栈。栈使用的是一级缓存,通常都是在调用时候存储于存储空间中,在用完后由编译器自动的释放。

堆: 为编程人员分配与释放,如果在程序结束的时候没有释放,一般会被OS所回收,分配方式类似于链表。堆一般存储于二级缓存。

数据结构, 堆可以被看成一棵树。栈则是一种先进后出的数据结构。

在具体介绍之前,我们应该介绍一下在C或者C++语言中变量的存储区域。

1,栈区(stack):这块区域由编译器分配与释放内存空间,一般存储函数的参数值与局部变量值。类似于数据结构中的栈。

2, 堆区(heap):这块区域由程序员自己分配与释放,其余数据结构中的堆是两码事,分配方式类似于链表。

3,全局区(静态变量区):这块存储区域用于存储全局变量(global)和静态变量(static),初始化的全局变量和静态变量存储于一块区域,未初始化的全局变量和静态变量存储于另一块区域。程序结束后系统自动释放。

4,文字常量区(静态缓冲区):这块区域用于存储常量静态字符串,在前面文章我有提到过并且演示过,用于存放const char*类型的变量。在程序运行中,是不可能对其进行修改的,如果修改的话,程序将会报错并且crush,程序结束后由系统自动释放。

5,程序代码区:该区域用于存放函数体的二进制代码。

下面,我用一段程序来解释在什么地方存放各种变量。



上面的例子完全诠释了各种变量存储的地方在程序中。

我们在申请空间的时候要注意的问题:

1,对于stack,如果我们申请的空间小于所剩余的空间,则系统会为其分配空间,如果大了的话,则会导致stack overflow,程序则会crush。

2,对于heap。 在计算机中,有一个记录空闲内存地址的链表,当系统收到申请的时候,系统就会遍历这个链表,寻找第一个大于申请内存空间的地址。之后便将这段内存分配给申请,同时会将这个节点从空闲内存节点中删除。值得一提的是,相对于大多数系统,会在这段内存空间的首地址记录本次分配内存的大小,因为这样,程序中的delete语句才可以正确的释放内存空间。同时,所分配的内存空间并不一定等于所申请的内存空间,再分配后,系统会将多余的内存重新加入内存空闲地址区域。

申请时应该注意的问题:在windows操作系统下,stack是一段由高地址向低地址扩展的连续内存,换句话说,也就是栈顶地址和栈的内存空间是系统设置好的。在大多数windows os中,栈的空间是2M,所以所申请的空间如果超过所剩余的栈的内存空间时候,栈就会overflow,程序就会报错。因此,能从栈中获得的内存空间较小。

相对于堆,堆是向高地址扩展的数据结构,是不连续的内存区域,为什么呢?因为系统使用链表进行存储的,必然不是连续的。堆的内存空间是受计算机中虚拟内存大小所控制的,因此用堆的话,获得的空间比较大,也比较灵活。

现在我们来讨论一下栈和堆申请内存的tradeoff:

1, 用栈申请内存的时候,有系统分配,速度较快,但是程序员没法直接控制。

2, 用堆申请内存空间的时候,分配内存空间相对来说较慢,但大小和销亡程序员可以控制,相对来说比较灵活,但是有时候容易产生内存碎片。

因此,具体问题具体分析,希望大家以后再写程序的时候,根据自己需求按照这两种规则进行不同的分配。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: