【问题标题】:Why is the iterator to the last element of the vector holding a corrupted value? (refer code)为什么指向向量最后一个元素的迭代器包含损坏的值? (参考代码)
【发布时间】:2019-08-15 08:56:18
【问题描述】:

下面的代码抛出 heap-use-after-free 错误。

#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,它显然会崩溃。 为什么这里的迭代器值似乎损坏了?

我尝试用列表替换向量,上面的代码工作正常。我想知道这是否与矢量如何在“push_back”上扩展有关。我已经尝试过其他方法来让迭代器到达向量的最后一个元素,但结果并不相同。

【问题讨论】:

标签: c++11 iterator stdvector stdlist


【解决方案1】:

当调用push_back 时,vector 中的迭代器和引用无效,请参阅reference。向量被实现为一个连续的内存块。当您推送新元素并且没有空间保留它们时,将分配新的内存块并添加新的元素。因此,指向旧元素的迭代器(指针)可能会失效。

您的代码可以在std::list 上运行,因为列表是使用 nodes 实现的。一个节点指向另一个节点,并且在将新数据添加到列表中时节点的位置不会改变,因此迭代器是有效的。

带有vector 的代码可以工作,但是您需要估计向量中可以保存多少元素,在创建向量后调用它reserve(N) - 它准备向量以保存N 项而不会使迭代器失效当push_back 被调用时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 2017-08-29
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多