Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么这个向量迭代器没有失效?_C++_Vector_Stl_Iterator_Invalidation - Fatal编程技术网

C++ 为什么这个向量迭代器没有失效?

C++ 为什么这个向量迭代器没有失效?,c++,vector,stl,iterator,invalidation,C++,Vector,Stl,Iterator,Invalidation,我读过一些关于迭代器失效的帖子,似乎需要向量重新分配的插入会使迭代器失效。也不应该在向量的中间擦除导致无效吗? 我不清楚这一点,不知道为什么在从开始、中间和结束调整大小和擦除之后使用这些迭代器不会破坏它们: #include <cstdlib> #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(int argc, ch

我读过一些关于迭代器失效的帖子,似乎需要向量重新分配的插入会使迭代器失效。也不应该在向量的中间擦除导致无效吗? 我不清楚这一点,不知道为什么在从开始、中间和结束调整大小和擦除之后使用这些迭代器不会破坏它们:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {

    vector<int> v;
    v.reserve(10);

    for (int i = 0; i < 10; i++)
        v.push_back(i);

    for (auto x = v.begin(); x != v.end(); x++) {
        cout << *x << endl;
    }

    cout << endl << "RESIZE" << endl << endl;

    for (int i = 10; i < 20; i++)
        v.push_back(i);

    for (auto x = v.begin(); x != v.end(); x++) {
        cout << *x << endl;
    }

    cout << endl << "RESIZE 2" << endl << endl;

    for (int i = 20; i < 200; i++)
        v.push_back(i);

    for (auto x = v.begin(); x != v.end(); x++) {
        cout << *x << endl;
    }

    cout << endl << "REMOVES" << endl << endl;

    v.erase(v.begin());
    v.pop_back();
    v.erase(v.begin() + 17);

    for (auto x = v.begin(); x != v.end(); x++) {
        cout << *x << endl;
    }

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
向量v;
v、 储备(10);
对于(int i=0;i<10;i++)
v、 推回(i);
对于(自动x=v.begin();x!=v.end();x++){

cout在您的代码中,当迭代器被重用时,始终没有对向量进行干预性修改,因此没有失效

迭代器在调整大小和插入时可能会失效。擦除只会使位于已擦除元素处或之后的迭代器失效


至少,这些是代码中
std::vector

的释义规则,在重用迭代器时,始终没有对向量进行干预性修改,因此没有失效

迭代器在调整大小和插入时可能会失效。擦除只会使位于已擦除元素处或之后的迭代器失效

至少,这些是
std::vector

的解释规则。请注意,调用begin()或end()将始终提供一个健全的迭代器

然而,类似于:

std:vector<int> v;
....

std::vector<int>::iterator i=v.begin();
v.erase(i);
std::cout << *i << std::endl;  // i iterator was invalidated by erasing it
                               // trying to access it or increment it is undefined behaviour.
std::cout << *v.begin() << std::endl;  // begin() provides always a sane iterator.
std:vectorv;
....
std::vector::迭代器i=v.begin();
v、 删除(i);
std::cout注意,调用begin()或end()将始终提供一个健全的迭代器

然而,类似于:

std:vector<int> v;
....

std::vector<int>::iterator i=v.begin();
v.erase(i);
std::cout << *i << std::endl;  // i iterator was invalidated by erasing it
                               // trying to access it or increment it is undefined behaviour.
std::cout << *v.begin() << std::endl;  // begin() provides always a sane iterator.
std:vectorv;
....
std::vector::迭代器i=v.begin();
v、 删除(i);

std::cout迭代器的有效性取决于容器的类型和操作。例如,对于vector::erase,请检查@Institute的迭代器有效性部分。我看不到这里有任何迭代器的重用。您能指出行吗您认为这是在哪种情况下发生的?在您的代码中,您每次迭代容器时都会捕获新的迭代器,因此您并不是在真正测试您提到的擦除和重新调整大小的情况。当您将say b.begin()的返回值复制到迭代器类型,然后调用v.push_back(…)时,迭代器将失效几次,然后尝试使用迭代器.Vectors,具有逻辑大小和物理大小。s.t.physical>=logical.Vectors是用连续内存实现的,因此当push_back(…)如果逻辑大小大于当前物理大小,则必须将基础内存复制到更大的连续内存块。迭代器具有指向该内存的内部指针,因此当该内存“增长”时操作发生迭代器现在在内部引用不再是向量一部分的内存块,因此它们无效。请尝试调用v.capacity(),并在初始化迭代器后将返回值存储在某个临时内存中。v.capacity()返回向量中当前分配的元素总数,并且大于或等于v.size()。现在调用v.push_back(…),直到向量的大小超过从capacity()返回的值存储在临时值中。当您将大小增加到超过上一个容量时,向量将增长,迭代器将失效。迭代器的有效性取决于容器的类型和操作。例如,对于vector::erase,请检查@Institute的迭代器有效性部分。在这里,我看不到任何迭代器的重用。您能指出您认为发生这种情况的行吗?在您的代码中,您每次迭代容器时都会获取新的迭代器,因此您并不是在真正测试您提到的擦除和重新调整大小情况。迭代器失效发生在您复制返回值时,例如b.begin()对于迭代器类型,然后调用v.push_back(…)几次,然后尝试使用迭代器.Vectors,具有逻辑大小和物理大小s.t.physical>=逻辑。向量是用连续内存实现的,因此当push_back(…)如果逻辑大小大于当前物理大小,则必须将基础内存复制到更大的连续内存块。迭代器具有指向该内存的内部指针,因此当该内存“增长”时操作发生迭代器现在在内部引用不再是向量一部分的内存块,因此它们无效。请尝试调用v.capacity(),并在初始化迭代器后将返回值存储在某个临时内存中。v.capacity()返回向量中当前分配的元素总数,并且大于或等于v.size()。现在调用v.push_back(…),直到向量的大小超过从capacity()返回的值存储在临时值中。当您将大小增加到超过上一个容量时,向量将增长,迭代器将无效。什么才是“中间修改”?我认为从中间删除肯定是正确的,并强制将所有元素的向量大小调整/复制到一个新的、更大的数组?是的,任何可能改变元素计数的内容。此外,显式保留空间。实际上,删除会使删除的迭代器之外的所有迭代器失效太好了。请参见@Deduplicator。那么为什么当
x
指向
v.begin()
时删除第一个元素不会使其无效?假设我没有像我原来的帖子中那样重新声明x,因为出于某种原因声明
auto x=v.begin()
在最初的10槽向量填充和从所有未来循环
x
中删除
auto
后,如果不重新声明,则仍然可以正常工作?它确实会失效。但这并不保证崩溃。此外,如果您指定一个新的,旧的将不复存在……究竟什么是“干预性修改”?我认为从中间擦除肯定是正确的,并强制将所有元素的向量调整大小/复制到一个新的、更大的数组?是的,任何可能