简体   繁体   English

Vector.erase(Iterator) 导致错误的 memory 访问

[英]Vector.erase(Iterator) causes bad memory access

I am trying to do a Z-Index reordering of videoObjects stored in a vector .我正在尝试对存储在vector中的videoObjects进行 Z-Index 重新排序。 The plan is to identify the videoObject which is going to be put on the first position of the vector , erase it and then insert it at the first position.计划是识别要放在vector的第一个 position 上的videoObject ,将其擦除,然后将其插入到第一个 position。 Unfortunately the erase() function always causes bad memory access.不幸的是, erase() function 总是导致错误的 memory 访问。

Here is my code:这是我的代码:

testApp.h:测试应用程序.h:

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

testApp.cpp:测试应用程序.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);
  }
}

This should be so simple but I just don't see where I'm taking the wrong turn.这应该很简单,但我只是不知道我在哪里走错了路。

You should do 你应该做

itVid = videoObjects.erase(itVid);

Quote from cplusplus.com : 来自cplusplus.com的报价:

[ vector::erase ] invalidates all iterator and references to elements after position or first . [ vector::erase ]使所有迭代器和位置第一个之后的元素引用无效。

Return value: A random access iterator pointing to the new location of the element that followed the last element erased by the function call, which is the vector end if the operation erased the last element in the sequence. 返回值:一个随机访问迭代器,指向函数调用擦除的最后一个元素后面元素的新位置,如果操作擦除了序列中的最后一个元素,则为向量结束。

Update: the way you access the current element inside your condition looks rather strange. 更新:您访问条件中当前元素的方式看起来很奇怪。 Also one must avoid incrementing the iterator after erase , as this would skip an element and may cause out-of-bounds errors. 还必须避免在erase后递增迭代器,因为这会跳过一个元素并可能导致越界错误。 Try this: 尝试这个:

for(itVid = videoObjects.begin(); itVid != videoObjects.end(); ){
  if(itVid->isInside(ofPoint(tcur.getX(), tcur.getY()))){
    itVid = videoObjects.erase(itVid);
  } else {
    ++itVid;
  }
}

Beware, erasing elements one by one from a vector has quadratic complexity. 注意,从矢量中逐个擦除元素具有二次复杂性。 STL to the rescue! 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()
);

You cannot delete while iterating over the list because the iterator gets invalid. 迭代列表时无法删除,因为迭代器无效。 You should use the return iterator of Erase to set it to your current iterator. 您应该使用Erase的返回迭代器将其设置为当前迭代器。

erase function returns the next valid iterator. erase函数返回下一个有效的迭代器。

You would have to make a while loop and do something like 你必须做一个while循环并做类似的事情

iterator = erase(...)

with corresponding checks. 有相应的检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM