C++中的内存分区

参考文章:
https://chenqx.github.io/2014/09/25/Cpp-Memory-Management/
https://www.cnblogs.com/youxin/p/3313288.html#commentform
(1)在C++中,内存分为5个区。分别是堆,栈,自由存储区,全局/静态存储区,常量存储区。
【1】栈:在执行函数时,函数内局部变量存储单元可以在栈上创建,函数执行结束时被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但容量有限。
【2】堆:就是那些由malloc分配的内存块,一般一个malloc对应一个free。如果程序员没有释放掉,那么在程序结束时,由操作系统自动回收。
【3】自由存储区:就是那些由new等分配的内存块,它和堆十分相似,不过它用delete来结束自己的生命。
【4】全局/静态存储区:全局变量和静态变量分配在同一个内存块中。
【5】常量存储区:分配的时常量,不允许修改。
(2)堆和栈的区别
【1】管理方式不同
对于栈,由编译器自动管理,无需我们手工控制;对于堆,释放工作由程序员操作。
【2】空间大小不同
对于堆,在32位系统下,可以达到4GB;对于栈来说,一般由一定的空间大小,可以在编译器中设置。
【3】碎片问题
对于堆来说,频繁的new/delete会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈则不会存在这个问题。
【4】生长方向不同
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,生长方向是向下的,是向着内存地址减小的方向生长。
【5】分配方式不同
堆都是动态分配的。栈有两种分配方式,静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配;动态分配由alloca函数进行分配,栈的动态分配由编译器释放。
【6】分配效率
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定的栈的效率比较高。堆则是由C/C++函数库提供的例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
为什么栈向下增长?
与虚拟地址空间的分配规则有关,对于一个可执行的C程序,地址分配如下,从低地址到高地址依次是:text,data,bss,堆,栈,环境变量参数;其中堆和栈有很大的地址空间闲着,在需要分配内存时,堆向上长,栈向下长。
如何验证
设计两个函数,一个作为调用方,另一个作为被调用方,被调用方以一个地址作为自己的入口参数,调用方传入的地址是自己的一个局部变量的地址,然后被调用方比较这个地址和自己的一个局部变量的地址。
计算机术语----栈帧:指的就是这些与一次函数调用相关的东西,而在一个栈帧内的这些东西其相对顺序是由编译器决定的,所以,在一个栈帧内做比较,都会对编译器有所依赖。

#include<stdio.h>

void func1();
void func2(int *a);

void func1()
{
    int a=0;
    func2(&a);
}
void func2(int *a)
{
    int b=0;
    printf("%x\n%x\n",a,&b);
}


int main()
{
    func1();
}

结果:
29f6ac
29f5c8
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值