2009-05-15 8 views
1

私はプログラムを作成し、vector.h #include、iteratorsなどを使用します。しかし、プログラムを実行すると、特定の状況下で(私はまだそれらが何であるか把握しようとしています)私はvector.hの98行目に私を参照しているアサーションエラーを取得します。私はvector.hの98行目に行って、これを得た:「ベクター」内のこのコードは何を意味していますか? (C++)

#if _HAS_ITERATOR_DEBUGGING 
     if (this->_Mycont == 0 
      || _Myptr < ((_Myvec *)this->_Mycont)->_Myfirst 
      || ((_Myvec *)this->_Mycont)->_Mylast <= _Myptr) 
      { 
      _DEBUG_ERROR("vector iterator not dereferencable"); 
      _SCL_SECURE_OUT_OF_RANGE; 
      } 

誰かがこの主張を引き起こしている私のプログラムではこれが何を意味し、何を教えていただけますか?

NB:ライン98は、記録のために、「_DEBUG_ERROR(」VECT ...」

NB始まるいずれかです。これは私がエラーを引き起こしたBELIEVE私のプログラムのコードですが、私は全くわからない、しかし

CODE:。

for(aI = antiviral_data.begin(); aI < antiviral_data.end();) 
    { 
     for(vI = viral_data.begin(); vI < viral_data.end();) 
     { 
      if((*aI)->x == (*vI)->x && (*aI)->y == (*vI)->y) 
      { 
       vI = viral_data.erase(vI); 
       aI = antiviral_data.erase(aI); 
      } 
      else 
      { 
       vI++; 
      } 
     } 
     if((*aI)->x >= maxx || (*aI)->x < 0 || (*aI)->y >= maxy || (*aI)->y < 0) 
     { 
      aI = antiviral_data.erase(aI); 
     } 
     else 
     { 
      aI++; 
     } 
    } 
+8

#を含めるだけで、vector.h、btwは含まれません。 – GManNickG

答えて

10

ランタイムは、あなたが前に()または終了後に()開始ですイテレータを参照外しされていることを検知している

ます場合を想像してみてください。 7行目でantiviral_dataベクトルの最後の項目を削除します。

aI = antiviral_data.erase(aI); 

aIantiviral_data.end()に設定され、ときに、ライン14であなたも間接参照を取得します:ライン5で

if((*aI)->x >= maxx ... 

とも:

if((*aI)->x == (*vI)->x 

範囲外のイテレータを逆参照しています。

修正プログラムは、消去呼び出し後にaI != antiviral_data.end()を確認して、使用を続行する前にベクターの最後に当たっていないことを確認してください。

7

実際にこのようなことを手動で行う代わりにremove_ifのようなSTLアルゴリズムを見たいと思っています。

5

小さな一般的なコメント:end()のイテレータをチェックするときは、 "<"を使用せず、 "!="だけを使用してください。だから、あなたのコードの最初の行は次のようになります。ジョシュは、すでに指摘したように

for(aI = antiviral_data.begin(); aI != antiviral_data.end();) 
{ 
    for(vI = viral_data.begin(); vI != viral_data.end();) 
    { 
    ... 

しかし、あなたの特定のバグは、ベクターすべてのイテレータを無効に内の要素を消去ラインに7

+0

「!=」を使用する理由を聞かれますか? –

+1

"より小さい"演算子はすべてのイテレータに対して定義されていません - この概要を参照してください:http://cplusplus.com/reference/std/iterator。ご覧のとおり、すべてのイテレータに対して不等式演算子が存在します。さらに、「より小さい」演算子は、不等式演算子(一定である)と比較してはるかに遅い(線形複雑性の可能性がある)かもしれない。 あなたのケースでは、イテレータ 'aI'が最後に小さいのかどうかを確認する必要はありませんが、あなたがまだ終わりに達していないことだけを確認してください。 – beef2k

-2

です。

+3

eraseから返されたイテレータは常に有効です(または少なくともend()と等しい) –

1
受け入れ答えに加えて

、およびslavy13の答えについて詳しく説明する -
( - ジョシュで述べたように、はこの質問に直接関係ない - EDIT私は参考のためにここでそれを残しています)。

コードから(ただしこのコードではない)、ベクターから要素を削除して反復処理を続けることができると想定されることがあります。これは誤った仮定です。つまり、要素をベクトルから削除すると、削除された要素に続く他のすべてのイテレータは無効になります。これらの要素が正しいとみなすことはできなくなり、使用し続けると「悪いこと」が起こります。

これは、ベクトルが実際に情報を配列形式で格納するためです。要素が削除されると、以降のすべての要素が1つ下にコピーされます。イテレータはそれに応じて更新されません。

このようなコードは、STLの特定の実装で誤って動作する可能性がありますが、他のコードでは失敗する可能性があるため、そのようなことを行うときは常にSTLのドキュメントを参照することを強くお勧めします。

関連する問題