0

valgrind で実行すると、サイズ 4 の無効な読み取りエラーが表示されるシングル スレッド プログラムがあります。

    void
 AccountStatus::transmitUpdate(int aiTuples, std::string& astrAliasPidf)
 {
  std::string lstrPidf;

  for (int i=0; i < TOTAL_TUPLE_COMBOS; i++)
  {
    if (_mSubList[i] != NULL)
    {
      GuidSubHandlerMap *subHandlerMap = _mSubList[i];

      if (this->getPidf (lstrPidf, i+1, aiTuples, astrAliasPidf, false) == -1)
        continue;

      ACE_DEBUG ((LM_DEBUG, ACCTPRES_DEBUG
        "transmitUpdate - created pidf for excludeMask [%X] with tuples [%X]\n", i+1, aiTuples));

      GuidSubHandlerMapIter iter;
      for (iter = subHandlerMap->begin(); iter != subHandlerMap->end(); iter++) //this line is shown as invalid read
      {
    subHandlerPtr lpHandler = iter->second;
    if (lpHandler)
    {
      lpHandler->queueNotify (CONTENT_TYPE, lstrPidf);
    }
  }
}
}
 }

イテレータを解放したとしてvalgrindに表示されている関数は次のとおりです。

    void
 AccountStatus::removeSubscription (const char *apcSubId, subHandlerPtr apHandler)
 {
  if (apcSubId && apHandler)
  {
    int excludeMask = apHandler->excludeMask();
    if (excludeMask != 0)
    {
      if (_mSubList[excludeMask-1] != NULL)
      {
        GuidSubHandlerMap *subHandlerMap = _mSubList[excludeMask-1];

        GuidSubHandlerMapIter iter = subHandlerMap->find (apcSubId);
        if (iter != subHandlerMap->end())
        {
          ACE_DEBUG ((LM_DEBUG, ACCTPRES_DEBUG
            "removeSubscription - [%s] mask [%X]\n", apcSubId, excludeMask));

          subHandlerMap->erase (iter); //this is where valgrind is showing memory being freed
        }
      }
    }
  }
 }

Valgrind の出力は次のとおりです。

    ==9130== Invalid read of size 4
==9130==    at 0x9566CC: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/libstdc++.so.6.0.8)
==9130==    by 0x23A954CD: std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >::operator++(int) (stl_tree.h:190)
==9130==    by 0x23AB4E01: ACCOUNT_PRESENCE::AccountStatus::transmitUpdate(int, std::string&) (accountStatus.cpp:518)

==9130==  Address 0x13604894 is 12 bytes inside a block of size 28 free'd
==9130==    at 0x400668A: operator delete(void*) (vg_replace_malloc.c:480)
==9130==    by 0x23A9647E: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*, unsigned int) (new_allocator.h:94)
==9130==    by 0x23A964B3: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::_M_put_node(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*) (stl_tree.h:362)
==9130==    by 0x23A96513: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::destroy_node(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*) (stl_tree.h:392)
==9130==    by 0x23A97F67: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >) (stl_tree.h:1189)
==9130==    by 0x23A97FA1: std::map<std::string, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler>, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >) (stl_map.h:446)
==9130==    by 0x23AB5515: ACCOUNT_PRESENCE::AccountStatus::removeSubscription(char const*, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler>) (accountStatus.cpp:314)

プログラムがシングルスレッドであると述べたように、なぜこのエラーが発生するのかわかりません。誰かがこれを引き起こしている可能性のあるものについて私を助けることができますか?

ありがとう

4

1 に答える 1

1

完全なコードを示していないため、言うのは難しいですが、繰り返し処理しているコンテナーを変更しないようにする必要があります。

この参照ページを見ると、次の行に気付くでしょう。

消去された要素への参照と反復子は無効になります。他の参照と反復子は影響を受けません。

したがって、消去された要素を指すイテレータを呼び出しeraseた後は無効になります。つまり、 eg を使用できなくなりますiter++

于 2012-08-31T05:03:34.307 に答える