【问题标题】:Calling the constructor of a large array of objects on a stack调用堆栈上大量对象的构造函数
【发布时间】:2011-02-04 01:57:09
【问题描述】:

我正在修改一些 C++ 源代码,我注意到作者确实不遗余力地分配堆栈上的所有内容。最有可能获得解除分配的好处(是否还有任何性能好处??)。

我想保持相同的一致性,但我需要创建大量对象,例如:

Object os[1000] = {Object(arg), Object(arg), ....};

不会剪掉它。搜索它似乎是一种解决方法:

vector<Object> os(1000, Object(arg));

这仍然在堆上分配,但像堆栈一样释放(来自我在其他帖子中读到的内容)。我只是想知道还有其他选择,因为这似乎是一个语法问题。也许聪明的#define 人都知道。

【问题讨论】:

  • 我的意思是这主要是在开玩笑,但也有一定的道理......有一个选择:学习如何使用指针和引用并进行设计,这样内存管理就不是问题了。
  • 性能优势:堆栈分配总是 O(1);堆分配是不确定的。
  • @Mehrdad:如果您使用的是具有无限堆栈的理想计算机,它们总是 O(1)...。在现实世界中,您最终分配的内存将超过当前的堆栈限制,而操作系统将不得不为您分配更多内存……或者在最坏的情况下,您将用完可用的堆栈空间,然后您的进程就结束了。跨度>
  • @Matti:好吧,我承认我没有想到 Stack Overflow(……是的……)。但老实说,堆栈扩展是一次性事件,只要您一次分配的空间不超过 2-4 KB(大约为 PAGE_SIZE),它们显然比堆分配要快。跨度>
  • @Mehrdad:他试图分配一千个不知道大小的对象。

标签: c++ arrays object constructor


【解决方案1】:

堆栈不应用于大内存块。您只需支付更高的堆分配价格,以换取访问更多内存的好处。另一种选择是声明一个具有静态存储持续时间的数组,但这有其他缺点(不可重入,非线程安全)。一切都是权衡。

无论如何,在分配复杂对象时,调用 1000 个构造函数的成本将使分配器所花费的时间相形见绌。只需使用std::vector,除非您的分析器数据显示存在性能问题。

【讨论】:

    【解决方案2】:

    是的,还有其他选择。你可以使用alloca 之类的东西。这将使您获得堆栈分配和自动释放,但不会自动构造或销毁。您需要使用放置 new 和显式调用析构函数。

    是的,可能有性能优势,但你也乞求破坏堆栈,并且这种模式不像 vector 解决方案那样异常安全(也就是说,如果你分配的对象有一个非-琐碎的析构函数)。

    【讨论】:

      【解决方案3】:

      一般来说,在堆栈上分配大量数据是一个坏主意。大多数操作系统上的堆栈是一个暂存空间,并且大小相当有限。为对象分配大量堆栈空间会很快消耗所有可用的堆栈空间,当某些东西试图在堆栈上再分配一个东西(例如,函数调用的返回地址)时,会导致段错误或其他异常。

      至于其他选项,您有几个......您已经注意到 std::vector 以及 boost::array 都是这样的例子。

      【讨论】:

        【解决方案4】:

        这应该可以工作:

        Object os[1000];
        os[0] = Object(args);
        std::copy(os, os + 999, os + 1);
        

        这会创建数组,初始化一个对象,然后循环遍历,用最后一个元素初始化每个元素。

        当然,您可能不应该使用它。即使它有效,即使Object os[1000] 不会给您带来问题,这似乎也是个坏主意。

        【讨论】:

          猜你喜欢
          • 2013-04-14
          • 2021-03-02
          • 1970-01-01
          • 2013-11-07
          • 1970-01-01
          • 2016-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多