4

我正在尝试对videoObjects存储在vector. 计划是确定videoObject要放在 的第一个位置的vector,将其擦除,然后将其插入到第一个位置。不幸的是,该erase()函数总是会导致错误的内存访问。

这是我的代码:

测试应用程序.h:

vector<videoObject> videoObjects;
vector<videoObject>::iterator itVid;

测试应用程序.cpp:

// Get the videoObject which relates to the user event
for(itVid = videoObjects.begin(); itVid != videoObjects.end(); ++itVid) {
  if(videoObjects.at(itVid - videoObjects.begin()).isInside(ofPoint(tcur.getX(), tcur.getY()))) {
   videoObjects.erase(itVid);
  }
}

这应该很简单,但我只是不知道我在哪里走错了路。

4

4 回答 4

15

你应该做

itVid = videoObjects.erase(itVid);

来自cplusplus.com的报价:

[ vector::erase] 使所有迭代器和对positionfirst之后元素的引用无效。

返回值:一个随机访问迭代器,指向函数调用擦除的最后一个元素之后的元素的新位置,如果操作擦除了序列中的最后一个元素,则该位置是向量结束。

更新:您在条件中访问当前元素的方式看起来很奇怪。还必须避免在 之后增加迭代器erase,因为这会跳过一个元素并可能导致越界错误。试试这个:

for(itVid = videoObjects.begin(); itVid != videoObjects.end(); ){
  if(itVid->isInside(ofPoint(tcur.getX(), tcur.getY()))){
    itVid = videoObjects.erase(itVid);
  } else {
    ++itVid;
  }
}
于 2010-05-31T13:47:37.757 回答
3

请注意,从向量中逐个擦除元素具有二次复杂度。STL来救援!

#include <algorithm>
#include <functional>

videoObjects.erase(
    std::remove_if(
        std::bind2nd(
            std::mem_fun_ref(&videoObject::isInside),
            ofPoint(tcur.getX(), tcur.getY())
        ),
    ),
    videoObjects.end()
);
于 2010-05-31T19:25:53.963 回答
1

迭代列表时不能删除,因为迭代器无效。您应该使用 Erase 的返回迭代器将其设置为您当前的迭代器。

于 2010-05-31T13:46:10.947 回答
0

erase函数返回下一个有效的迭代器。

你必须做一个while循环并做类似的事情

iterator = erase(...)

有相应的检查。

于 2010-05-31T13:47:42.017 回答