我有std::vector<SomeType>
,而SomeType
是从各种模板参数中实例化的struct
。
最终,在我的具体情况下,它结果是一个大型结构(大约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_back
,而每个新元素都在堆上分配。但所有这一切都不可避免地涉及额外的代这是没有道理的。
有没有办法达到我的需要?鉴于:
std::vector<SomeType>
提前致谢
答案 0 :(得分:4)
在C ++ 03中,这是不可能的:
因此您需要复制元素。它不适合堆栈(排除默认参数),你不想明确地把它放在别处,所以你运气不好。
在C ++ 11中,有一种初始化容器中元素的新方法,例如size_t
构造函数不再需要额外的默认参数。相反,它会初始化每个元素,这可能就是你想要的。
所以在C ++ 11中,答案是std::vector<SomeType> myVec(N);
。也许您可以检查您的编译器是否具有可用于编译代码的C ++ 11模式。当然,迁移到C ++ 11并不是完全无足轻重的。
答案 1 :(得分:2)
使用reserve然后使用push_back。
答案 2 :(得分:2)
最佳解决方案是更改SomeType
以使其更小。但是可以在不使用堆栈或堆的情况下调整向量的大小。只需使用静态局部变量:
static SomeType intialValue;
myVec.resize(N, initialValue);
请注意,此类功能不可重复使用。