SIGSEGV when reserving a vector stored in a class



(请参阅编辑(这是我在一大块代码中遇到的问题的最小示例(请参阅下面的代码(。我有几个向量,用来存储输入数据。在读入一些数据之前,这些向量没有设置的大小。一旦读入数据,数据就会存储到向量中,所以我需要设置向量的大小,填充向量,然后继续将向量用于其他目的(这就是为什么我想把它们放入类中(。我有一些测试代码做得很好(类似于下面的foo()(,然后将其全部转移到我的生产代码中(类似于以下的bar()(。然而,bar()出现故障,我不确定原因。有没有一种合适的方法来存储向量并保留/填充它,以便稍后在这样的类中使用?

#include <iostream>
#include <vector>
int VSIZE = 5;
class foobar {
public:
foobar() { initialize(); };
~foobar() = default;
static void foo();
void bar();
private:
void initialize() { bar(); };
std::vector<std::vector<uint32_t>> vec1;
};
// This succeeds.
void foobar::foo() {
std::vector<std::vector<uint32_t>> vec2;
vec2.reserve(VSIZE);
for(int i=0;i<VSIZE;i++){
vec2[i].emplace_back(0);
}
std::cout << "Finished foo." << std::endl;
}
// This fails.
void foobar::bar() {
// Reserve the needed memory for vec1.
vec1.reserve(VSIZE);
for(int i=0;i<VSIZE;i++){
// Reserve the needed memory for each vector within vec1.
vec1[i].reserve(VSIZE);
}
for(int i=0;i<VSIZE;i++){
vec1[i].emplace_back(0);
}
std::cout << "Finished bar." << std::endl;
}
int main() {
foobar::foo();
foobar TC;
}

该代码的输出是

Finished foo.
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

编辑:好吧……我必须制定一个更好的最小示例,因为我刚刚意识到,根据注释,用resize替换所有保留区在这段代码中非常有效。然而,它们在我的生产代码中不起作用,因为我已经尝试过了,而且刚刚又尝试过。我必须弄清楚有什么不同,并进一步修改这个问题。

解决方案

第2版:新的一天,在阅读了这里的评论后,我设法解决了我的问题。除了我的多维向量外,我把所有的储备都留下了。通过首先对这些向量使用resize,然后进一步保留其包含的向量,我的问题得到了解决。因此,对于上述情况,我将条形图修改为

void foobar::bar() {
// Resize vec1 to allocate the needed storage.
vec1.resize(VSIZE);
for(int i=0;i<VSIZE;i++){
// Reserve the needed memory for each vector within vec1.
vec1[i].reserve(VSIZE);
}
for(int i=0;i<VSIZE;i++){
vec1[i].emplace_back(0);
}
std::cout << "Finished bar." << std::endl;
}

崩溃发生在这里:

#0  0x0000555555556352 in __gnu_cxx::new_allocator<unsigned int>::construct<unsigned int, int> (this=0x55555556deb0, __p=0x0) at /usr/include/c++/9/ext/new_allocator.h:147
#1  0x0000555555555cd7 in std::allocator_traits<std::allocator<unsigned int> >::construct<unsigned int, int> (__a=..., __p=0x0) at /usr/include/c++/9/bits/alloc_traits.h:484
#2  0x000055555555582e in std::vector<unsigned int, std::allocator<unsigned int> >::emplace_back<int> (this=0x55555556deb0) at /usr/include/c++/9/bits/vector.tcc:115
#3  0x0000555555555367 in foobar::bar (this=0x7fffffffdcc0) at foo.cc:35
#4  0x00005555555554e8 in foobar::initialize (this=0x7fffffffdcc0) at foo.cc:14
#5  0x00005555555554ad in foobar::foobar (this=0x7fffffffdcc0) at foo.cc:8
#6  0x00005555555553b1 in main () at foo.cc:42

在帧#2中:

#2  0x000055555555582e in std::vector<unsigned int, std::allocator<unsigned int> >::emplace_back<int> (this=0x55555556deb0) at /usr/include/c++/9/bits/vector.tcc:115
115         _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
(gdb) p this->_M_impl._M_finish
$1 = (std::_Vector_base<unsigned int, std::allocator<unsigned int> >::pointer) 0x0

这就是你的答案:即使为vec1[]的元素保留了存储空间,但还没有构建任何元素。

您的代码相当于:

std::vector<int> *v = (std::vector<int> *) malloc(sizeof(*v));
v->emplace_back(0);

这应该很明显为什么不起作用。

相关内容

  • 没有找到相关文章

最新更新