【问题标题】:C++ When to allocate on heap vs stack?C++ 何时在堆和栈上分配?
【发布时间】:2013-09-26 10:15:22
【问题描述】:

在问另一个问题(以及之前)时,我想知道如何判断是在堆上创建对象还是将其作为堆栈上的对象保留?关于对象,我应该问自己什么才能进行正确的分配?

【问题讨论】:

    标签: c++ memory-management heap-memory stack-memory


    【解决方案1】:

    如果需要,将其放在堆上,如果可以,则放在堆栈上。

    你需要把什么样的东西放在堆上?任何长度不一的东西。任何可能需要为空的对象。任何非常大的东西,以免导致堆栈溢出。

    【讨论】:

    • 我同意你的说法,但我不明白 "任何可能需要为空的对象" 。 “空”是什么意思?当然不是传统的NULLnullptr
    【解决方案2】:

    简单的答案。

    当它超出范围时,您是否希望它挂起并能够使用它?

    【讨论】:

    • 应该注意的是,将巨大的对象放在堆栈上也不是一个好主意,即使它们满足其他条件。尤其是在 C++ 中超出你的堆栈限制没有乐趣..
    • @Voo 是的,但这种情况多久发生一次?容器类动态分配它们的内存,所以我认为可以肯定地说一个大小为 1KB 的对象是(a)巨大的和(b)罕见的。让我们考虑一个深度为 50 的调用堆栈,每个函数的堆栈帧中有 20 个这样的巨大对象,而您仍然只有 1MB 堆栈。
    • @voo - 您可以增加堆栈大小。您也可以在没有堆的情况下编写代码 - 这是各种安全关键行业的要求,
    • 并且必须更改特定于操作系统的限制来执行您的代码并不会让您觉得设计特别糟糕?如果限制取决于输入大小,则尤其成问题。 @us2012 罕见情况?我真的希望如此,但这与关于如果您恰好属于其中之一的建议有什么关系?
    • @voo - 如果软件有固定的输入(如发电站一样),并且软件需要长时间 24 x 7 运行,避免内存碎片和与悬空指针相关的问题,那么没有。欢迎来到安全关键软件的世界#
    【解决方案3】:

    取决于对象的预期生命周期。

    • 如果您希望对象在函数返回后仍处于活动状态,则为 HEAP,否则为 STACK

    如果一个对象被放置在 HEAP 中,那么一旦它的使用结束,程序员必须显式地释放或删除它;否则程序会泄漏内存。

    【讨论】:

    • 当然,除非您从函数中返回所述对象。那么在很多情况下,通过值而不是指向它的指针返回对象是好的。
    • 需要考虑静态数据
    【解决方案4】:

    使用堆的两个原因:

    1- 你想要当前范围之后的数据。

    2- 你想保留大内存。

    除此之外留在堆栈上。

    注意:不要在堆栈上保留大量内存,否则会出现“堆栈溢出”;)

    【讨论】:

      【解决方案5】:

      堆栈内存很快。它很快,因为 (a) 没有系统开销来分配内存 - 分配是通过简单地在一条指令中移动堆栈指针来完成的,并且 (b) 堆栈中的内存是“热的”,因此它已经在缓存中。堆内存很慢,因为 (a) 它需要大量的系统工作来环顾四周并找到空闲的内存块,并且 (b) 可能不在缓存中,并且需要逐出一些您可能想要的数据。

      堆栈内存不会碎片化。有可能堆最终会变得如此碎片化,您无法分配任何东西(尽管具有讽刺意味的是仍有足够的未使用内存!)

      对于长期存在的数据和大数据(多 KB 或更多),您必须使用堆。

      分配更大堆栈的危险在于,如果正在运行多个线程,它可能会伤害您。您必须为“最坏情况”使用调整堆栈大小。每个线程都需要自己的堆栈。在高核心数机器上(您可能有 200 多个线程在运行),您可能不想随意增加堆栈。另一方面,堆不需要为“最坏情况”的使用而调整大小 - 它效率更高。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        • 1970-01-01
        • 2017-01-04
        • 2017-08-12
        • 2011-09-14
        • 2011-08-04
        • 2020-08-24
        相关资源
        最近更新 更多