4

videoObjectsに保存されている Z-Index の並べ替えを実行しようとしていvectorます。videoObject計画は、 の最初の位置に置かれるを特定し、それvectorを消去してから、最初の位置に挿入することです。残念ながら、この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);
  }
}

これはとても単純なはずですが、どこで間違った方向に進んでいるのかわかりません。

4

4 に答える 4

15

やったほうがいい

itVid = videoObjects.erase(itVid);

cplusplus.comからの引用:

[ vector::erase] はすべての反復子と、positionまたはfirst の後の要素への参照を無効にします。

戻り値: 関数呼び出しによって消去された最後の要素に続く要素の新しい位置を指すランダム アクセス反復子。これは、操作によってシーケンス内の最後の要素が消去された場合のベクトルの終わりです。

更新:条件内の現在の要素にアクセスする方法はかなり奇妙に見えます。また、 の後にイテレータをインクリメントしないようにする必要があります。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

ベクトルから要素を 1 つずつ消去すると、2 次複雑になることに注意してください。救助に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 の return イテレータを使用して、現在のイテレータに設定する必要があります。

于 2010-05-31T13:46:10.947 に答える
0

erase関数は、次の有効な反復子を返します。

whileループを作成して、次のようなことをする必要があります

iterator = erase(...)

対応するチェック付き。

于 2010-05-31T13:47:42.017 に答える