C++-c++中在堆和栈中申请空间的差别?
这次设计一个类来模拟列表控件(非windows MFC中的CListCtrl空间), 在类中有个map成员变量, 它用来存储list相关数据. 现在两种选择map<UINT,CItemData>或者map<UINT,CItemData*>, CItemData中存储了每行list的信息, 我现在纠结的是: 我是使用哪种? 其实本质上是想知道堆中和栈中申请的空间的比较, 我找到了下面的比较:
栈的情况:
栈上分配空间的好处是快,而且对象生存期是自动的,离开当前域之后就自动析构回收。
坏处就是栈空间有限,而且不能人为控制对象的生存期,
比如你无法将一个函数内部的栈上的对象返回,因为这个函数执行完毕后栈空间会自动回收。
堆的情况
堆上分配空间就相反,new一个空间出来是较慢的,而且对堆上对象的访问也稍慢于栈上。
一旦new一个空间出来,需要自己手动去delete回收,系统不会帮你管理回收(用GC的除外),
但是分配空间大小灵活,而且正因为是手动回收的,你可以自由控制对象生存期,常用来跨域传递对象。
我现在想说说如果我能保证delete的调用, 也不太关心这一点效率问题, 我想问: 堆对比栈还有哪些劣势? 比如, 分配的成功率有没有栈高? 我会不会分配失败的情况比栈高? .........
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
栈的话就程序变量存在的内存空间,程序通过栈不断变化来控制它的访问区域,如进入一个函数的话,主函数的栈就会被屏蔽掉,而新延长一个栈,就无法访问主函数栈中的数据,退出函数的同时又返回栈中。
堆的话就是一个程序不会自动去管理的空间,在程序运行时如果不被释放是随时可以访问。程序结束的时候就会释放,也常常导致内存泄漏等等。
个人更喜欢使用堆,但是前提是自己要想清楚如何管理内存,因为堆不会有大小限制,而且我是在linux下开发的,所以碎片回收上要相对理想一些。
把内存的管理交给自己而不是依赖系统,真正出问题的时候也好排错。
堆中的空间是动态申请的 运行时才分配的,栈中的空间是在编译时,链接器进行链接的时候就会确定其地址的,我们申请的局部变量就是栈空间。堆与栈相比劣势什么的我觉得谈不上,作用不同,不好评价。就比如静态数组和动态数组,当他们用来存储输入的时候,由于无法确定输入数量,无疑动态在这里更适合。
从效率上来说,村冲在栈中效率是更好的,因为在编译时就会确定其地址。但是在堆中申请空间则不同,要动态的分配地址,有时还会要与物理地址建立映射,开销是比栈更大的。
这里附图一张,可供加深理解
仔细看了 的问题,我觉得你想多了。
是堆还是栈,并不决定是用map<UINT,CItemData>还是用map<UINT,CItemData*>
比如:
{
map<char,CItemData> idMapA;
map<char,CItemData*> idMapB;
CItemData id1;
CItemData* id2 = new CItemData;
idMapA['a'] = id1;
idMapB['a'] = &id1;
idMapA['b'] = *id2;
idMapB['b'] = id2;
}
delete id2;
两个map都能用,只不过 mapA效率稍差,多了一次值拷贝.
既然两个都能用,那么我认为你的主要问题应该是CItemData对象的生存周期问题,
1.如果CItemData 对象和map对象生存周期一致,如上例,那么用什么无所谓。
2.如果CItemData 对象是全局对象,或者说CItemData 对象的生存期要长于map对象,那么我建议用 mapB,毕竟少了一次值拷贝。
3.如果CItemData 对象是局部变量,或者说CItemData 对象的生存周期短于map对象,那么就得用mapA。
不知道我的描述是否清楚,因为现在用的这台电脑上没有编译器,凭感觉写的代码不知道有没有什么问题。
堆和栈的区别:
管理方式不同:栈是由编译器自动管理的。堆的释放工作是由程序员来控制的(delete),容易忽略。
空间大小不同:栈,一般都是有一定的空间大小。堆内存几乎是不受限制的。
碎片的产生:堆,频繁的new/delete势必会造成内存空间的不连续,造成大量的碎片空间,程序效率降低。栈,不会存在这个问题,栈是先进后出的队列,所以永远不可能在内存块中间出现碎片。
分配方式不同:堆是动态分配的,没有静态分配的堆。栈有两种分配方式:静态和动态,静态分配时编译器自己完成的(局部变量)动态分配是由alloca函数进行分配。
分配效率不同:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持。堆是C++函数库提供的,机制比较复杂,所以栈的分配效率比堆的效率高。
个人认为堆内存相对栈内存的第一个劣势就是内存管理需要使用者自己来,这个问题可以使用智能指针一类的工具来搞定;而另一个劣势就是申请和释放内存的效率问题,因为堆内存是在运行时动态像操作系统申请的,这个问题也是可以通过内存池等方法来解决的,采用这种方法的话分配成功率也会大大提高,同时也减少了内存碎片的出现。而在量上,堆内存是远远超过栈内存的。