内存分区那些事

在c++中,内存分成以下几个区:栈、堆、自由储存区、全局/静态存储区和常量存储区

1、栈(stack)

由编译器在需要的时候自动分配,不需要的时候自动清除的储存区。在分配和清除是都不需要程序员干预,

全由编译器进行管理。这个区通常存放的变量为局部变量、函数形参等

2、堆(heap)

一般由程序员分配和释放,如果程序员没有释放,那么在程序结束后有操作系统自动回收。这个去是那些由

new分配的内存块,它们的释放编译器不去管,由程序员去进行控制。一般一个new就要对于一个delete。

3、自由储存区(free store)

就是那些有malloc等分配的内存块,它和堆是十分相似的,不过他是用free来释放内存的。

4、全局/静态区(static)

全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量由分为初始化的哈为初始化的,

在C++里面没有这个分区了,他们共同占用同一块内存区。程序结束后有系统自动释放。

5、常量储存区

这是一款比较特殊的储存区,它们里面存放的是常量。


对于上面的内存分区,关于new和malloc在内存的分区有些争议。有些资料说new和malloc都是放在堆中

的,也有些资料说malloc放在堆中,new放在自由储存区中的。鄙人目前暂时也找不到权威的资料,希望

大家可以分享一下自己的见解。


另外一个比较重要的问题就是堆和栈的区别,它们的区别主要有一下几点:

1、管理方式不同

对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产

内存泄露

2、空间大小不同

一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但

是对于栈来讲,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超

过栈的剩余空间时,将提示溢出因此,能从栈获得的空间较小。

3、碎片产生不同

对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。

对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都

不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出

4、生长方向不同

对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下

的,是向着内存地址减小的方向增长。 

5、分配方式不同

堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器

完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他

的动态分配是由编译器进行释放,无需我们手工实现。 

6、分配效率不同

栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压

栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是

很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作

系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片

太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,

然后进行返回。显然,堆的效率比栈要低得多。 


说了那么多,举一个例子来补充说明一下:

int i=10;//全局/静态区(static)
int j;//全局/静态区(static)
main()
{
    int x;//栈
    char s[]="string";//栈
    char *p1;//栈
    char *p2="string";//p2在栈上,“string”在常量区
    char *p3=new[5];//p3在栈上,在栈内存中存放了一个指向一块堆内存的指针p3
}

习题练兵一下:

Class A{}
void function(A a1)
{
    A a2=a1;
}

main()
{
    A a3;
    A *a4=new A;
}

请问a1 a2 a3 a4 这四个变量是在内存的哪些区?


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值