如何决定堆栈上的内容

How to decide what goes on stack?

本文关键字:堆栈 何决定 决定      更新时间:2023-10-16

假设我有一个名为MainComponent的C++类,它里面有几个类:WindowClass,InputClass,GameClass。主函数设置如下:

int main()
{
    MainComponent app;
    app.start(); // Initializes the MainComponent class, opens window, starts game and all that.
    return 0;
}

由于包含的GameClass等对象,预计MainComponent类可能会变得非常大。主组件应用程序是否应该动态分配新的?还是应该在主组件类中使用 new 来分配游戏类对象?或者只要它运行良好,就可以将其留在堆栈上还是什么?

取决于"大"的含义。此链接显示某些操作系统的默认堆栈大小限制。您需要确保MainComponent在堆栈上分配的大小远低于这些数字中的任何一个。

此外,如果动态创建某些东西,或者某些数组/资产太大,属于MainComponent或其他低于MainComponent的结构,那么你总是可以堆分配该结构/数组/类,同时仍然将 MainComponent 本身保留在堆栈上。

从概念上讲,将MainComponent保留在堆栈上更有意义,因为它的生命周期是由其在main函数中的范围精确建模的。

要回答您更一般的问题,如何决定堆栈上的内容?,请考虑三个方面:

  1. 所有权。特定数据结构的所有权是否明确?它是否明确属于特定函数(及其后代)或特定结构/类,并且可以使用 RAII 建模?
  2. 生命周期。特定数据结构是否应存在于与创建它的类的生存期或创建它的函数非常相似的时间线中?范围是什么?
  3. 编译时大小是否已知? 这在分配可变大小的数组时出现。许多 STL 容器就是这种情况。在这种情况下,基本结构/类在堆栈上包含一些内容,然后维护指向堆分配结构的指针。

你说:

预计 MainComponent 类可能会变得非常大,因为 包含的游戏类对象

例如:空std::string与非常长的std::string具有相同的sizeof,对于任何对象都是相同的。

sizeof(object)是它在堆栈上占用的唯一字节。 无论如何,其余的都进入了堆。

因此,如果您达到堆栈限制并出现堆栈溢出异常,那么您应该尝试将一些对象移动到堆中。 或者,如果它是一个对象(就像您的MainComponent类一样),您也可以使用 singleton 模式,或者只是将其声明为 static ,将其从堆栈中删除到其他内存段。