C++内存管理之一---------内存分配方式

C++内存管理之一---------内存分配方式

1.内存分配方式简介

在C++中,内存分为5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

,在执行函数时,函数内局部变量的存储单元可以在栈上创建,函数执行结束时这些存储单元自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

,由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,由malloc等分配的内存块,它和堆非常相似,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中。在c语言中,全局变量又分为初始化和未初始化的。在c++里面没有这个区分了,它们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,它们里面存放的是常量,不允许修改。

2.明确区分栈和堆

void f() {
	int *p = new int[5];
}
上面程序的意思是:在栈内存中存放了一个指向一块堆内存的指针p。程序会先确定堆中分配内存的大小,然后调用operator new 分配内存,然后返回这块内存的首地址。

3.堆和栈究竟有什么区别?

堆和栈的区别有一下几点:

1).管理方式不同     2).空间大小不同    3).能否产生碎片不同     4).生长方向不同    5).分配方式不同    6).分配效率不同

管理方式:对于栈,是由编译器自动管理,无需我们手工控制;对于堆,释放工作由程序员控制,容易产生memory leak.

空间大小不同:一般在32位系统下,堆内存可以达到4G的空间,从这个角度看堆内存是没有什么限制的。但是对于栈,一般都是有一定的空间大小的。

碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来说,则不会有这个问题。因为栈是先进后出的队列,它们是如此的一一对应,以至于永远都不可能有一个内存块从栈中弹出,在它弹出之前,在他上面的后进的栈内容已经被弹出。

生长方向:堆,生长方向是向上的,也就是向着内存地址增加的方向;栈,生长方向是向下的,是向着内存地址减小的方向增长。

分配方式:堆都是动态分配的。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由malloc函数进行分配,但是栈的动态分配和堆是不同的,他的分配是由编译器进行释放,无需我们手工实现。

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都由专门的指令执行,这就决定了栈的效率比较高。堆则是c/c++函数库提供的,他的机制很复杂。

总结:堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以在程序中栈是应用最广泛的。就算是函数调用也利用栈去 完成,函数调用过程中的参数,返回地址,局部变量都采用栈的方式存放。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值