为什么指向向量最后一个元素的迭代器持有损坏的值? (参考代码)
Why is the iterator to the last element of the vector holding a corrupted value? (refer code)
下面的代码抛出堆释放后使用错误。
#include <iostream>
int main()
{
unordered_map<int, vector<int>::iterator> mp;
vector<int> num;
auto insert = [&](int n)
{
if (mp.count(n) != 0)
return false;
num.push_back(n);
mp[n] = prev(num.end());
return true;
};
insert(1);
insert(2);
insert(3);
for (auto n : num)
cout << n << endl;
cout << endl;
for (auto m : mp)
{
cout << m.first << " -> ";
cout << distance(num.begin(), m.second) << endl;
// cout << *m.second << endl;
}
return 0;
}
以上代码的输出为
1
2
3
3 -> 2
1 -> -16
2 -> -7
如果我尝试访问 *m.second
,它显然会崩溃。
为什么这里的迭代器值似乎已损坏?
我试过用列表替换向量,上面的代码工作正常。我想知道这是否与 vector 在 "push_back" 上的扩展方式有关。我尝试了其他方法使迭代器指向向量的最后一个元素,但结果无关紧要。
调用 push_back
时,vector
中的迭代器和引用无效,请参阅 reference。 Vector 被实现为一个连续的内存块。当您推送新元素并且没有 space 来保留它们时,将分配新的内存块并添加新的元素。因此指向旧元素的迭代器(指针)可能会失效。
您的代码适用于 std::list
,因为列表是使用 nodes 实现的。一个节点指向另一个节点,同时将新数据添加到节点的列表位置不会改变,因此迭代器是有效的。
您使用 vector
的代码可以工作,但您需要估计向量中可以包含多少元素,在创建向量后调用它 reserve(N)
- 它准备向量来保存 N
项在调用 push_back
时不会使迭代器无效。
下面的代码抛出堆释放后使用错误。
#include <iostream>
int main()
{
unordered_map<int, vector<int>::iterator> mp;
vector<int> num;
auto insert = [&](int n)
{
if (mp.count(n) != 0)
return false;
num.push_back(n);
mp[n] = prev(num.end());
return true;
};
insert(1);
insert(2);
insert(3);
for (auto n : num)
cout << n << endl;
cout << endl;
for (auto m : mp)
{
cout << m.first << " -> ";
cout << distance(num.begin(), m.second) << endl;
// cout << *m.second << endl;
}
return 0;
}
以上代码的输出为
1
2
3
3 -> 2
1 -> -16
2 -> -7
如果我尝试访问 *m.second
,它显然会崩溃。
为什么这里的迭代器值似乎已损坏?
我试过用列表替换向量,上面的代码工作正常。我想知道这是否与 vector 在 "push_back" 上的扩展方式有关。我尝试了其他方法使迭代器指向向量的最后一个元素,但结果无关紧要。
调用 push_back
时,vector
中的迭代器和引用无效,请参阅 reference。 Vector 被实现为一个连续的内存块。当您推送新元素并且没有 space 来保留它们时,将分配新的内存块并添加新的元素。因此指向旧元素的迭代器(指针)可能会失效。
您的代码适用于 std::list
,因为列表是使用 nodes 实现的。一个节点指向另一个节点,同时将新数据添加到节点的列表位置不会改变,因此迭代器是有效的。
您使用 vector
的代码可以工作,但您需要估计向量中可以包含多少元素,在创建向量后调用它 reserve(N)
- 它准备向量来保存 N
项在调用 push_back
时不会使迭代器无效。