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

Invalid pointer operation error when calling vector.erase() function

本文关键字:指针 操作 无效 错误 函数 vector erase 调用      更新时间:2023-10-16

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

我有一个类定义的对象的向量,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);
    }

*注意我知道有一个明确的函数可以更整洁地做到这一点,但这只是我正在尝试做的其他事情的简化示例

与往常一样,在遍历范围时修改范围时,不能无条件地递增循环计数器。

考虑一个双元素集合的简单示例。当i 0时,删除第一个元素并递增i。现在i 1bar.size() 1,循环退出,无法删除第二个元素。

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

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

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

(这是一个非常常见的错误,尽管通常它用迭代器来表示,例如这里或这里或这里。

问题是循环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)
{ ..... }