0

我有一个std::vector<SomeType>, 而SomeTypestruct从各种模板参数实例化的。

最终在我的具体情况下,它变成了一个大型结构(大约 1MB)。在堆栈上分配这样的结构(即使用这种类型的自动变量)会立即导致堆栈溢出。但是由于std::vector在堆上分配内存-应该没有问题。

令人惊讶的是,这有一个问题。具体来说,问题在于初始化。我执行以下操作:

std::vector<SomeType> myVec;
// ...
myVec.resize(N);
for (size_t i = 0; i < N; i++)
{
    SomeType& x = myVec[i];
    // initialize it
}

我在myVec.resize(). 使用调试器进入内部resize()显示,如果resize()导致vector增长 - 除了分配内存之外,它还通过“默认值”初始化新元素。

“默认值”是通过创建给定类型的自动变量、使用默认(即空)构造函数并将新元素分配给它来获得的。

我想知道是否有办法克服这个问题。我的意思是,告诉std::vector不要初始化新元素。但我想在不生成不需要的代码的情况下实现这一点。

我可以考虑使用一个vector(智能/共享/作用域/唯一)指针来输入。或者使用push_backwhile 每个新元素都分配在堆上。但是所有这些不可避免的都涉及额外的代码。这是不合理的。

有没有办法实现我所需要的?然而:

  • 仍在使用std::vector<SomeType>
  • 没有多余的堆分配

提前致谢

4

3 回答 3

4

在 C++03 中这是不可能的:

  • 向量不能包含未初始化的元素
  • 向量知道如何通过复制来初始化元素

因此,您需要一个从中复制的元素。它不适合堆栈(排除默认参数)并且您不想明确地将其放在其他地方,所以您不走运。

在 C++11 中,有一些新方法可以初始化容器中的元素,例如size_t构造函数不再需要额外的默认参数。相反,它对每个元素进行值初始化,这可能是您想要的。

所以在 C++11 中,答案是std::vector<SomeType> myVec(N);. 也许您可以检查您的编译器是否具有可用于编译代码的 C++11 模式。当然,迁移到 C++11 并不是一件容易的事。

于 2012-07-31T12:54:39.747 回答
2

使用reserve,然后push_back。

于 2012-07-31T12:49:40.663 回答
2

最好的解决方案是进行更改SomeType以使其更小。但是在不使用堆栈或堆的情况下调整向量的大小是可能的。只需使用静态局部变量:

static SomeType intialValue;
myVec.resize(N, initialValue);

请注意,此类功能不可重入。

于 2012-07-31T13:02:45.697 回答