C++中数据存储的位置

C++中数据存储的位置

转大神的博客,原文链接

一个由 c/c++编译过的程序占用的内存分为以下几个部分:

  1. 栈区: 就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。
    里面的变量通常是局部变量函数参数等。

  2. 堆区(动态内存分配): 通过new和malloc分配,由delete或free手动释放或者程序结束自动释放。
    动态内存的生存期人为决定,使用灵活。
    缺点是容易分配/释放不当容易造成内存泄漏,频繁分配/释放会产生大量内存碎片。
    若程序员不释放,程序结束时可能由OS(操作系统)回收。
    注意它与数据结构中的堆是两回事,分配方式类似于链表。

  3. 全局区(静态区)static : 全局变量和静态变量的存储是放在一块的。
    在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区,程序结束后由系统释放。

  4. 常量存储区: 这是一个比较特殊的存储区,里面存放的是常量,不允许修改。程序结束后由系统释放。

  5. 程序代码区: 存放函数的二进制代码。

下面说一下栈存储和堆存储的区别:

栈存储: 栈存储通常用于存储占用空间小,生命周期短的数据,如局部变量和参数变量等。只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆存储: 由于大量 new / delete 的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时, 会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

在地址分配方面:

  1. 对于堆来讲,向着内存地址增加的方向;
  2. 对于栈来讲,向着内存地址减小的方向增长。

联系:小尾端是高位字节在高端地址、低位字节在低位地址,因此在压栈时先压高字节后压低字节

分配效率:

  1. 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。
  2. 堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。

显然,堆的效率比栈要低得多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值