阿里笔试题:C++中的内存分配

有这样一道阿里笔试题:

C++内存分配中说法错误的是( )。
A.对于栈来说,生长方向是向上的,也就是向着内存地址增加的方向
B.对于堆,大量的new/delete操作会造成内存空间不连续
C.堆容易产生memory leak
D.堆的效率比栈要低很多
E.栈变量引用容易逃逸
F.以上都对

【答 案】A、F

【解 析】C++将各类变量分配在不同的区域中,主要有栈、堆、自由存储区、全局/静态存储区及常量存储区等。

题目中提到的几种存储空间的特性如下。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。栈中的变量通常是局部变量、函数参数等。在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。用户栈在程序执行期间可以动态地扩展和收缩。因为栈具有先进后出的特点,故它的生长方向是向下的,是向着内存地址减小的方向增长。选项A是错误的。

堆,就是那些由new分配的内存块,这种内存的释放不由编译器管理,而由应用程序去控制。一般来说,一个new就要对应一个delete。如果程序员没有释放掉,会导致一直占据该内存单元,即所谓内存泄漏(选项C是正确的)。这些内存在程序结束后,操作系统才会自动回收。

对于堆来讲,频繁的new/delete操作势必会造成内存空间的不连续(选项B是正确的),从而造成大量的碎片,这会使程序效率降低(选项D是正确的)。对于栈来讲,则不会存在这个问题,因为栈是先进后出的,不可能有一个内存块从栈中间弹出,所以不会有碎片产生。

在计算机语言编译器语言优化管理中,当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。分析指针动态范围的方法称之为逃逸分析。当一个对象的指针被多个方法或线程引用时,这个指针就发生了逃逸。例如在一个方法b内部生成的一个对象V的引用,返回给另一个方法a内的变量v时,或方法c内生成的一个对象W被赋给了全局变量global_v,就发生了指针(引用)逃逸。故选项E是正确的。

本文已收录于《横扫Offer--程序员招聘真题详解700题》一书,开点工作室著,清华大学出版社。更多程序员笔试面试真题的精彩详解请参见该书。

为保证书稿质量,作者及出版社在编写完成后经过反复多次的审核、校对和修改,力求为读者奉献一本内容详实、严谨、准确、精美的实用宝典,因此上市时间有所延后,望各位读者谅解。该书目前已进入印刷环节,预计8月下旬各大网上书店开始发售。我们将会在第一时间通知该书的上市购买信息,并将举行评论送书活动,以感谢各位读者的支持。详细情况请持续关注微信公众账号“开点工作室”。

推荐阅读更多精彩内容

  • JVM内存模型Java虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是: ...
    禅与计算机程序设计艺术阅读 2,035评论 2 26
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,396评论 1 16
  • 浅红淡白间深黄,簇簇新妆阵阵香。 无限枝头好颜色,可怜开不为重阳。 明•丘濬《咏菊》
    我心飞扬3666阅读 311评论 0 1
  • 作业:抽4张卡 1、人像卡:代表现在你正在压抑的自己是什么样子的?通过这张牌,你联想到了什么事情?心里乱七八糟的样...
    韦梅梅阅读 64评论 0 0
  • 还能坚持吗?还能吧。 又开始给自己找理由吗?还是真的是思考?实在佩服自己的脑力,冥冥之中,假的也能被自己给说服成真...
    轻诉离愁阅读 30评论 0 0