【问题标题】:Dynamic allocation or automatic recommended for subsystem creation?建议动态分配还是自动创建子系统?
【发布时间】:2011-07-01 16:22:10
【问题描述】:

我是一名 C++ 程序员爱好者,目前正在开发一款游戏(使用 Ogre3D),我对我的主类的内存分配有疑问。

我已经阅读了很多关于内存分配、在堆栈上自动分配和在堆上动态分配的内容,以及它们的区别(性能、有限的堆栈大小)。我仍然不确定我的主类(Application)和其他一些“工厂”类(由 Application 类的单个实例创建)使用什么,它们在整个执行过程中都存在一个实例。

下面是布局的简化sn-p:

int main() 
{
    // like this (automatic)
    Application app;
    app.create();    // initializing
    app.run();       // runs the game-loop

    // or like this (dynamic)
    Application* app;
    app = new Application();
    app->create();
    app->run();

    return(0);       // only reached after exiting game
}



class Application
{
public:
    Application();   // ctor
    ~Application();  // dtor

    // like this, using 'new' in ctor and 'delete' in dtor (dynamic)
    SceneManager* sceneManager_;   // a factory for handling scene objects
    DebugManager* debugManager_;   // a factory for handling debugging objects

    // or like this (automatic)
    SceneManager sceneManager_;
    DebugManager debugManager_;
};

在堆栈上还是在堆上分配内存更好(应用程序类和工厂类)?以及依据什么论据?

提前致谢!

【问题讨论】:

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


    【解决方案1】:

    总是更喜欢自动分配而不是动态分配。当您需要动态分配时,请确保其生命周期由自动分配的资源包装器(如智能指针)管理。

    【讨论】:

    • 感谢您的回答。不过,这对我提出了更多问题。我不会通过自动分配这些“长期存在”的主类来冒险达到堆栈限制,因为这个堆栈空间只有在退出游戏后才会被释放?此外,对象的创建和删除是直接完成的(通过 Application 类的创建和删除),无疑会造成内存泄漏。动态分配导致的性能下降并不重要,因为这些对象仅在启动时创建一次(加载屏幕)。遵循这些论点动态分配是首选,对吧?
    • @Bash:不,因为你的论点中没有任何东西是建立在任何经验之上的。你有什么证据表明你正在做的堆栈空间不足?只需像往常一样将它放在堆栈上,如果堆栈空间成为问题(即崩溃,它很可能永远不会)然后动态分配它。正确性是您最关心的问题,而不是试图解决尚未显现的虚构问题。
    • 感谢您的明确答复!我会坚持这个解释。然而,这有点令人困惑,看到关于这个话题的不同意见。
    【解决方案2】:

    在这种情况下,我认为这一切都归结为大小。

    您不想浪费堆栈空间,所以要么使用 new 的动态分配,要么将 Application 作为全局变量放在 main() 之外。

    【讨论】:

      【解决方案3】:

      在 C++ 中,问题要复杂得多,但一般来说,您无法避免在堆上进行分配。例如,您的new 操作正在堆上分配您的Application 对象——new 在运行时动态分配内存,其中auto 内存的分配在编译时确定 . (当然,它实际上是在运行时分配的——但它是在启动代码根据编译后的分配为main 创建堆栈时分配的。)

      现在,您为什么要想要避免在堆上分配?这可能是因为堆大小有限,但对于现代机器来说,这几乎不是问题,即使在手持设备中也是如此。然而,堆栈空间可能很有限。这就是堆的争论。

      当然,auto 内存不会“泄漏”——但在主(或文件范围内,尽管这是静态的)分配的内存不会被释放,因此几乎可以声称它是“自动”泄漏的.

      我认为这里的基本问题实际上是“为什么你在堆上分配?”主要原因通常是为了避免内存泄漏,但是小心使用new/delete 可以保护您免受这种情况的影响——并且考虑到库​​中无处不在的动态分配等,即使您设计了,您也不能停止考虑良好的内存卫生避免动态分配。

      【讨论】:

      • 感谢您的回复。 Jason Gregory 的“游戏引擎架构”一书提出了以下经验法则:“将堆分配保持在最低限度......”,正如许多人所说。我为什么要在这里“违反”这条规则?
      • 有点取决于“最低限度”的定义。但是想想你因为避免动态分配而失去了什么:想想像适应工作负载的动态数据结构,或者在拥有它的系统中使用更多内存的能力。如果他们的意思是“在有用时使用动态分配,但不要因为可以随意动态分配东西”,那么当然。
      猜你喜欢
      • 2014-01-14
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 2013-07-27
      相关资源
      最近更新 更多