Vector.erase(Iterator) 导致内存访问错误

发布于 2024-09-03 06:31:36 字数 647 浏览 5 评论 0原文

我正在尝试对存储在 vector 中的 videoObjects 进行 Z 索引重新排序。计划是识别要放置在矢量第一个位置的视频对象,将其删除,然后将其插入到第一个位置。不幸的是,erase() 函数总是会导致错误的内存访问。

这是我的代码:

testApp.h:

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

testApp.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);
  }
}

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

I am trying to do a Z-Index reordering of videoObjects stored in a vector. 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. Unfortunately the erase() function always causes bad memory access.

Here is my code:

testApp.h:

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

testApp.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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤城病女 2024-09-10 06:31:36

您应该

itVid = videoObjects.erase(itVid);

引用 cplusplus.com

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

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

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

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

You should do

itVid = videoObjects.erase(itVid);

Quote from cplusplus.com:

[vector::erase] invalidates all iterator and references to elements after position or first.

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. Try this:

for(itVid = videoObjects.begin(); itVid != videoObjects.end(); ){
  if(itVid->isInside(ofPoint(tcur.getX(), tcur.getY()))){
    itVid = videoObjects.erase(itVid);
  } else {
    ++itVid;
  }
}
战皆罪 2024-09-10 06:31:36

请注意,从向量中一一删除元素具有二次复杂度。 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()
);

Beware, erasing elements one by one from a vector has quadratic complexity. STL to the rescue!

#include <algorithm>
#include <functional>

videoObjects.erase(
    std::remove_if(
        std::bind2nd(
            std::mem_fun_ref(&videoObject::isInside),
            ofPoint(tcur.getX(), tcur.getY())
        ),
    ),
    videoObjects.end()
);
风吹过旳痕迹 2024-09-10 06:31:36

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

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.

北笙凉宸 2024-09-10 06:31:36

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

您必须创建一个 while 循环并执行类似

iterator = erase(...)

相应检查的操作。

erase function returns the next valid iterator.

You would have to make a while loop and do something like

iterator = erase(...)

with corresponding checks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文