计算机中堆栈的概念

这两天学习win32的API, 了解到了计算机中堆栈的概念,相信很多程序员有时候也弄不明白计算机中的堆栈的数据结构。再次为堆栈做一下详细解析。在英文中,我们管栈称为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, 用堆申请内存空间的时候,分配内存空间相对来说较慢,但大小和销亡程序员可以控制,相对来说比较灵活,但是有时候容易产生内存碎片。

因此,具体问题具体分析,希望大家以后再写程序的时候,根据自己需求按照这两种规则进行不同的分配。

说了这么多,相信大家也有所了解了,同时大家再仔细的思考一下,函数退scope的时候也是按照这种规则的。马上临近春节了,在美国给大家拜个早年,蛇年快乐!

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值