C++ c++;向量的向量迭代器

C++ c++;向量的向量迭代器,c++,vector,segmentation-fault,C++,Vector,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;

为什么我会出现分割错误

    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];
std::载体细胞;
std::vector cellitr;

对于(int i=0;i,程序中有两个未定义行为的来源

首先,执行此操作时:

c.push_back(j);
cellitr.push_back(citr);
您正在增加向量的大小。如果向量的大小超过其容量,则向量必须重新分配更大的存储以容纳其当前元素和新元素,这是因为向量必须始终将元素存储在连续的存储区域中

当发生重新分配时,迭代器将失效。特别是,您的迭代器
citr
可能在插入之前以这种方式获得:

citr= c.begin();
将无效。取消引用无效迭代器会在程序中注入未定义的行为

,执行此操作时:

c.push_back(j);
cellitr.push_back(citr);
您正在将迭代器存储到向量(
c
),当循环退出时,该向量将超出范围-这将使存储的迭代器成为无效迭代器。同样,取消引用无效迭代器将导致未定义的行为


为了避免两种未定义行为的来源,您可以按如下方式更改循环:

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());
}
cells.reserve(10);

对于(int i=0;i,程序中有两个未定义行为的来源

首先,执行此操作时:

c.push_back(j);
cellitr.push_back(citr);
您正在增加向量的大小。如果向量的大小超过其容量,则向量必须重新分配更大的存储以容纳其当前元素和新元素,这是因为向量必须始终将元素存储在连续的存储区域中

当发生重新分配时,迭代器将失效。特别是,您的迭代器
citr
可能在插入之前以这种方式获得:

citr= c.begin();
将无效。取消引用无效迭代器会在程序中注入未定义的行为

,执行此操作时:

c.push_back(j);
cellitr.push_back(citr);
您正在将迭代器存储到向量(
c
),当循环退出时,该向量将超出范围-这将使存储的迭代器成为无效迭代器。同样,取消引用无效迭代器将导致未定义的行为


为了避免两种未定义行为的来源,您可以按如下方式更改循环:

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());
}
cells.reserve(10);
对于(int i=0;i,此处将
c
的副本推入
单元格中

cells.push_back(c);
这里,您将迭代器存储到局部向量
c
,其生存期仅为for循环的一次迭代:

cellitr.push_back(citr);
您将迭代器存储到本地向量,并尝试在这些向量不存在的范围内访问它们

除此之外,由于
c
的增长,可能会出现一些迭代器无效问题。这可以通过调用
c.reserve(10)
来解决,但您必须先解决另一个问题:

std::vector<int> c;
....
cellitr.push_back(cells.back().begin());
std::向量c;
....
cellitr.push_back(cells.back().begin());
此处,将
c
的副本推入
单元格中

cells.push_back(c);
这里,您将迭代器存储到局部向量
c
,其生存期仅为for循环的一次迭代:

cellitr.push_back(citr);
您将迭代器存储到本地向量,并尝试在这些向量不存在的范围内访问它们

除此之外,由于
c
的增长,可能会出现一些迭代器无效问题。这可以通过调用
c.reserve(10)
来解决,但您必须先解决另一个问题:

std::vector<int> c;
....
cellitr.push_back(cells.back().begin());
std::向量c;
....
cellitr.push_back(cells.back().begin());

在这种情况下,您可能应该避免使用迭代器。迭代器太不稳定。请尝试保留索引。但我需要在给定索引中插入值,而不仅仅是向后推,如何在没有迭代器的情况下执行?函数insert必须有一个迭代器作为输入。您可以使用
v.begin()为任何索引创建迭代器+index
在这种情况下,您可能应该避免使用迭代器。迭代器太不稳定了。请尝试保留一个索引。但我需要在给定的索引中插入值,而不仅仅是向后推,没有迭代器如何做?函数insert必须有一个迭代器作为输入。您可以使用
v.begin()为任何索引创建迭代器+index
感谢您提供了这个很好的答案,如果我需要在给定向量的给定索引中插入一个值,您知道如何在没有迭代器的情况下插入值吗???@AhmedKato:我扩展了答案:)谢谢你的回答,如果我需要在给定向量的给定索引中插入一个值,你知道没有迭代器怎么做吗???@AhmedKato:我扩展了答案:)