スポンサーリンク

std::listを使っていてlist iterators incompatibleが出た。

以下のプログラムをデバッグモードで(←重要)走らせたところエラーが発生。

#include <iostream>

#include <list>

int main()
{

  std::list<int> aa,bb;
  aa.push_back(0);
  bb.push_back(1);

  // 違うリストのイテレータを比較
  if (aa.begin() == bb.begin())
    std::cout << "same" << std::endl;

}
Expression: list iterators incompatible

原因と王道的な回避策

このエラーは、

・違うリストのイテレータ同士を比較し

かつ

・_ITERATOR_DEBUG_LEVEL==2の時

のとき起こる。だからデバッグーモードでは起こるがリリースモードでは起こらないということがありうる。

このエラーが出ている個所のコードを抜粋すると以下のようになっている。

  _NODISCARD bool operator==(const _List_const_iterator& _Right) const noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
    _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "list iterators incompatible");
#endif // _ITERATOR_DEBUG_LEVEL == 2

    return this->_Ptr == _Right._Ptr;
  }

つまりイテレータのoperator==()の中でイテレータの正当性をチェックし、意味のない比較が行われたときは意図してエラーを出している。

従って、

/D"_ITERATOR_DEBUG_LEVEL=0"

などを指定してやれば回避できる。

 

ほかの解決方法を考える

この部分はイテレータの正当性をチェックし意図的に発生させているエラーなので、自前で書いてしまえばoperator==の前に検出できる。

#include <iostream>

#include <list>

int main()
{

  std::list<int> aa,bb;
  aa.push_back(0);
  bb.push_back(1);

  std::list<int>::iterator i1 = aa.begin();
  std::list<int>::iterator i2 = bb.begin();

#if _ITERATOR_DEBUG_LEVEL==2
  // デバッグ時、異なるリスト同士の比較が生じる前にチェックする
  if (i1._Getcont() != i2._Getcont()) {
    std::cout << " i1 != i2 " << std::endl;
  }
  else 
#endif
  {
    // デバッグ時、異なるリスト同士の比較が生じることはない
    if (i1 == i2) {
      std::cout << "i1 == i2" << std::endl;
    }
    else {
      std::cout << "i1 != i2" << std::endl;
    }
  }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: