调用vector.erase()函数时,指针操作错误无效

时间:2017-03-22 23:30:17

标签: c++ vector stl runtime-error invalidoperationexception

我正在使用vector :: erase()函数删除向量中的第一个元素,直到它为空,但我的编译器给出了“无效的指针操作”错误。

我有一个类定义对象的向量,foo,叫做bar。 我正在逐个删除元素:

for(int i = 0; i < bar.size(); i++){ 
        if(!bar.empty()){
            bar.erase(bar.begin()); 
        }
}

当我运行我的程序时,它只完成一次迭代(无论大小)并在第二次中断。 具体来说,它打破了STL函数_Destroy

template<class _TyDtor> inline
    void _Destroy(_TyDtor _FARQ *_Ptr)
    {   // destroy object at _Ptr
    _DESTRUCTOR(_TyDtor, _Ptr);
    }

*注意我知道有一个明确的功能可以更整齐地做到这一点,但这只是我想要做的其他事情的简化示例

2 个答案:

答案 0 :(得分:2)

与遍历范围时修改范围一样,您无法无条件地增加循环计数器。

考虑两元素集的简单示例。当i0时,您删除第一个元素并增加i。现在i1bar.size()1,循环退出,无法删除第二个元素。

标准解决方案是使增量以而不是修改容器为条件:

for (int i = 0; i < bar.size(); /* no increment here */) { 
    if (!bar.empty()) {
        bar.erase(bar.begin());
    } else {
        ++i;
    }
}

当您通过擦除元素来修改容器时,i保持不变,但范围会使一个元素移近它。增加i也会重复计算。

(这是一个非常常见的错误,但通常用迭代器表示,例如hereherehere。)

答案 1 :(得分:0)

问题是循环bar.size()的条件部分在每次迭代中不断变化,即在此示例中减少1。

很难说你在循环中想要实现什么,但如果你想执行循环bar-size ()次,那么使用跟随逻辑:

const size_t vecSize = bar.size ()
for(int i = 0; i < vecSize ; i++) 
{ ..... }

否则,如果要执行循环直到bar-size ()为空,则使用while循环,如下所示:

while (bar.size > 0)
{ ..... }