C语言基础 | 关于堆与栈的一些知识点

首先先区分一下堆(heap)与栈(stack):

1、申请方式和回收方式不同

栈 是系统自动分配空间的,如我们定义char c,系统就自动在栈上为其开辟空间。栈上的数据用完后就会自动释放,生命周期就只是函数运行过程中。

堆 是需要程序猿自己申请的空间,如malloc,calloc、realloc等。堆上数据只要程序猿不执行free就一直可以被访问。

2、申请后系统的响应

栈:只要栈的剩余空间大于所申请的空间,系统就会为程序提供内存。

堆:操作系统由记录空闲空间内存地址的链表。系统收到程序申请时会遍历链表寻找第一个空间大于所申请的空间的堆结点,然后将该结点从空闲链表中删除,并将该结点空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的 delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。 

3、申请效率不同

栈:由系统自动分配,速度较快,但程序猿无法控制。

堆:由new分配内存,速度较慢,用起来方便,但是容易产生内存碎片。

4、申请大小的限制

栈:向低地址扩展的数据结构,是一块连续的内存区域。栈的大小一般是系统预定好的,会overflow。

堆:向高地址扩展的数据结构,是一块不连续的内存区域。堆的大小受限于计算机系统的有效虚拟内存。

5、堆栈中存储内容

栈:调用函数 => 紧接着的第一条指令地址入栈 => 参数入栈 => 局部变量入栈(函数调用结束后出栈顺序反之)。

堆:一般是在堆的头部用一个字节存放堆的大小,堆中内容由程序猿安排。

6、存取效率不同

栈 在运行时赋值; 堆 在编译时赋值。

存取速度:栈比堆快。

拓展:

一、数据结构中的堆和栈:

栈:先进先出的数据结构,形如开口容器。

堆:经过排序的树形数据结构,通常指二叉堆,存取随意,形如书架。

二、堆栈溢出一般是由什么原因导致的?

1、函数调用层次太深。函数递归调用时,系统要在栈中不断保存函数调用时的现场和产生的变量,如果递归调用太深,就会造成栈溢出,这是递归无法返回。再有,当函数调用层次过深时也有可能导致栈无法容纳这些调用的返回地址而造成栈溢出。

2、动态申请空间使用之后没有释放。由于C语言中没有垃圾资源自动回收机制,因此,需要程序主动释放已经不再使用的动态地址空间。申请的动态空间使用的是堆空间,动态空间使用不会造成溢出。

3、数组越界访问。C语言没有提供数组下标越界检查,如果程序中出现数组下标访问超出数组范围,在运行过程中可能会内存访问错误。

4、指针非法访问。指针保存了一个非法地址,通过这样的指针访问所指向的地址是会产生内存数据访问错误。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值