下面的代码引发“堆后释放后使用”错误。
#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
,显然会崩溃。
为什么这里的迭代器值似乎被破坏了?
我尝试用list替换vector,并且上面的代码工作正常。我想知道这是否与向量如何在“ push_back”上扩展有关。我尝试了其他方法来使迭代器到达向量的最后一个元素,且结果无关紧要。
答案 0 :(得分:0)
调用vector
时,迭代器和引用在push_back
中无效,请参见reference。向量被实现为一个连续的存储块。当您推送新元素并且没有空间保留它们时,将分配新的内存块并添加新的elem。因此,旧元素的迭代器(指针)可能无效。
您的代码可在std::list
上使用,因为列表是使用 nodes 实现的。一个节点指向另一个节点,并且在将新数据添加到节点的列表位置时不会更改,因此迭代器有效。
您的带有vector
的代码可以使用,但是您需要估算向量中可以包含多少个元素,在创建向量后调用reserve(N)
-它准备将向量保存{{1 }}项,而在调用N
时不会使迭代器无效。