堆栈理解

堆栈理解

一、一个c/c++ 编译的程序大概占用内存的分为以下几部分

1栈区 由编译器自动分配释放,存放的有函数参数和临时变量等

2堆区 一般有程序员分配释放,若程序员不释放,在程序结束的时候可能有os回收。分配方式像链表

3全局区(静态区)全局变量和静态变量的存储是放在一起的。初始化的放在一起,没初始化的在相邻的另一块区域,程序结束后由系统释放。

4文字常量区 常量字符串就是放在这个区,程序结束后由系统释放

5程序代码区 - 存放函数体的二进制代码

//main.cpp
int a = 0; //全局初始化区
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main() {
int b; //栈
char s[] = “abc”; //栈
char *p2; //栈
char *p3 = “123456”; //123456\0在常量区,p3在栈上。
static int c = 0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//分配得来得10和20字节的区域就在堆区。
strcpy(p1, “123456”); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

二、申请方式

(1)栈:只要栈的剩余空间大于所申请空间,系统就会为其提供内存,否则就将会报异常提示栈溢出
(2)堆:操作系统有一个记录空闲地址的链表,当我们申请内存时,系统会遍历这个链表 找到第一个空间大于申请空间的节点,将空间分配给程序,然后将节点从空闲列表中删除。另外,对于大多数系统会在这块内存的首地址记录本次分配的大小。这样delete方法才能正确的释放内存空间。除此,该节点的空间大小如果大于所需分配的内存大小,空余的将重新放回到空闲列表中去
限制大小:
栈是向低地址扩展的数据结构,是一块连续的地址内存。 也就是栈顶的位置和最大容量是系统预先规定的,这个值是编译时就确定的一个值,容量较小。
堆是向高地址扩展的数据结构,是不连续的内存区域。空闲区域用链表管理,遍历的方向也是从低地址想高地址。堆的大小受限于计算机系统中的有效的虚拟内存。堆空间比较大,并且灵活。
申请效率:
栈是系统自动分配,速度较快。但是程序员是无法控制的
堆通过new分配内存,一般速度慢,并且容易产生内存碎片,不过用起来方便

.堆和栈溢出总结

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值