[英]c++ iterators for vector of vectors
Why I am getting a segmentation fault ?? 为什么我遇到细分错误?
std::vector<std::vector<int> > cells;
std::vector<std::vector<int>::iterator> cellitr;
for(int i=0;i<10;i++)
{
std::vector<int> c;
std::vector<int>::iterator citr;
citr= c.begin();
for(int j=0;j<10;j++)
{
c.push_back(j);
}
cells.push_back(c);
cellitr.push_back(citr);
}
qDebug()<<cells[5][6];
int *x = &cells[5][6];
cells[5].insert(cellitr[5],200);//SEG FAULT HERE
qDebug()<<cells[5][6];
I have a vector of vectors and vector of iterators and I am trying to insert a value in one of the sub vectors using the index of the iterator. 我有一个向量vectors和一个迭代器vector,我正在尝试使用迭代器的索引在一个子向量中插入一个值。
any idea ?? 任何想法 ??
There are two sources of undefined behavior in your program. 程序中有两种未定义行为的来源。
First , when you do this: 首先 ,当您执行此操作时:
c.push_back(j);
You are incrementing the size of the vector. 您正在增加向量的大小。 If the size of the vector exceeds its capacity, the vector has to reallocate a bigger storage to hold its current elements and its new element - that's because vectors must always store elements in a contiguous region of storage.
如果向量的大小超过其容量,则向量必须重新分配更大的存储空间以容纳其当前元素和新元素-这是因为向量必须始终将元素存储在连续的存储区域中。
When reallocation occurs, iterators are invalidated. 重新分配发生时,迭代器将失效。 In particular, it is possible that your iterator
citr
obtained this way prior to insertions: 特别是,您的迭代器
citr
可能是在插入之前以这种方式获得的:
citr= c.begin();
Will be invalidated. 将无效。 Dereferencing an invalid iterator injects undefined behavior in your program.
取消引用无效的迭代器会在程序中注入未定义的行为。
Second , when you do this: 其次 ,当您执行此操作时:
cellitr.push_back(citr);
You are storing an iterator to a vector ( c
) that will go out of scope when the loop exits - that will make the stored iterator an invalid iterator. 您正在将迭代器存储到向量(
c
),该向量将在循环退出时超出范围-这将使存储的迭代器成为无效的迭代器。 Again, dereferencing an invalid iterator will give you undefined behavior. 再次,取消引用无效的迭代器将给您未定义的行为。
In order to avoid both sources of undefined behavior, you could change your loop as follows: 为了避免两种未定义行为的来源,您可以按以下方式更改循环:
cells.reserve(10);
for(int i=0;i<10;i++)
{
std::vector<int> c;
for(int j=0;j<10;j++)
{
c.push_back(j);
}
cells.push_back(c);
cellitr.push_back(cells.back().begin());
}
Notice, that in C++11 you could avoid the inner loop and make the above more compact: 注意,在C ++ 11中,您可以避免内部循环并使上面的代码更紧凑:
#include <algorithm> // For std::iota() (C++11 only)
// ...
cells.reserve(10);
for(int i=0;i<10;i++)
{
std::vector<int> c(10);
std::iota(c.begin(), c.end(), 0);
cells.push_back(c);
cellitr.push_back(cells.back().begin());
}
Here, a copy of c
is pushed into cells
: 在这里,
c
的副本被推入cells
:
cells.push_back(c);
Here, you store an iterator to a local vector c
, whose lifetime is only one single iteration of the for-loop: 在这里,您将迭代器存储到本地向量
c
,该向量的生存期仅为for循环的单次迭代:
cellitr.push_back(citr);
You are storing iterators to local vectors, and trying to access them in a scope where these vectors do not exist. 您正在将迭代器存储到本地向量,并尝试在不存在这些向量的范围内访问它们。
Besides this, there may be some iterator invalidation issues due to the growth of c
. 除此之外,由于
c
的增长,可能存在一些迭代器失效问题。 This can be fixed via a call to c.reserve(10)
, but you have to fix the other problem first: 这可以通过调用
c.reserve(10)
来解决,但是您必须首先解决另一个问题:
std::vector<int> c;
....
cellitr.push_back(cells.back().begin());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.