当前位置:首页 > 芯闻号 > 充电吧
[导读]首先,我们举一个例子:    void f() { int* p=new int[5]; }     这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢

首先,我们举一个例子:
    void f() { int* p=new int[5]; } 
    这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:
    00401028   push        14h
    0040102A   call        operator new (00401060)
    0040102F   add         esp,4
    00401032   mov         dword ptr [ebp-8],eax
    00401035   mov         eax,dword ptr [ebp-8]
    00401038   mov         dword ptr [ebp-4],eax
    这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。

    主要的区别由以下几点:
    1、管理方式不同;
    管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
    2、空间大小不同;
  一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改:    
    打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。
注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。
   3、能否产生碎片不同;    对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。
  4、生长方向不同;   对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
  5、分配方式不同;   堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
 6、分配效率不同;   栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
    从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。
    虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。
    无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的:)
    对了,还有一件事,如果有人把堆栈合起来说,那它的意思是栈,可不是堆,呵呵,清楚了?

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2026年3月19日 /美通社/ -- 2026世界一级方程式赛车锦标赛(以下简称F1)中国大奖赛正赛上周在上海国际赛车场落幕。作为F1官方物流合作伙伴,DHL与这项全球...

关键字: 可持续发展 BSP 供应链 环境影响

西班牙马德里2026年3月19日 /美通社/ -- ABB国际汽联电动方程式世界锦标赛第12赛季的第六回合比赛,即将于2026年3月21日首次在哈拉马赛道拉开帷幕。 FE电动方程式正式将马德里纳入赛历,这座西班牙城...

关键字: 电动 测试 快充 TC

纽约和印度诺伊达2026年3月19日 /美通社/ -- 全球领先的科技公司HCLTech(NSE:HCLTECH)(BSE:HCLTECH)被定义和推进商业道德标准...

关键字: ISP LTE HC SE

新加坡2026年3月20日 /美通社/ -- MetaOptics Ltd (Catalist: 9MT)(「MetaOptics」或「本公司」,连同其子公司统称「本集团」)近日于新加坡交易所公告一系列策略性增长举措,包...

关键字: OPTICS 新加坡 AI ADS

苏州2026年3月20日 /美通社/ -- 与非网宣布,聚焦半导体领域的垂直AI工具——与非AI(www.eefocus.com/ai-chat/)正式上线,旨在破解工程师在器件选型、替代料查询、方案研发中的效率瓶颈,以...

关键字: 工程师 器件选型 AI 半导体

上海2026年3月20日 /美通社/ -- 为学术出版生态提供AI与专家解决方案的技术公司CACTUS(Cactus Communications),近日宣布与全球学术出版机构Taylor & Francis续签...

关键字: CIS PAPER TAYLOR FLIGHT

杭州2026年3月20日 /美通社/ -- 3月13日, 国际第三方检测认证机构TÜV南德意志集团(以下简称"TÜV南德")为杭州海康...

关键字: 智能车 汽车智能 汽车产业 智能驾驶

上海2026年3月19日 /美通社/ -- 三月春深,万物竞发,绿色生机成为各行各业高质量发展的鲜明底色。对于正处于深刻变革中的汽车产业而言,绿色发展不仅是趋势,更是驱动技术进化与价值重构的核心力量。中国汽车工...

关键字: 新能源汽车 轮胎 P10 BSP

北京2026年3月20日 /美通社/ -- 全球领先的半导体公司Analog Devices,Inc. (Nasdaq:ADI)宣布公司在泰国新落成的先进制造工厂已经正式启用。此举将进一步提升ADI的先进制造与测试能力,...

关键字: ADI ANALOG AI STATE

北京2026年3月20日 /美通社/ -- 近年来,算力已成为驱动产业升级、支撑科技创新的核心生产力。作为全国一体化算力网络建设的重要参与者,软通智算聚焦算力网运营核心赛道,近期在三大国家枢纽节点接连取得突破性...

关键字: 节点 BSP 网络建设 全栈
关闭