2012-08-31 1 views
0

У меня есть однопоточная программа, которая показывает недопустимую ошибку чтения размером 4 при работе с valgrind.valgrind показывает неверную ошибку чтения в std :: map

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) 

Как я отмечал, что программа однопоточен , Я не знаю, почему эта ошибка. Может ли кто-нибудь помочь мне с тем, что может быть причиной этого?

Благодаря

+0

Можете ли вы дать нам [минимальный полный пример] (http://sscce.org/)? – Beta

+0

Кажется «что-то» с контейнером, Уотсон. Пожалуйста, покажите весь код, который связан с контейнером :) – xtofl

ответ

1

Вы не показывают полный код, так что трудно сказать, но вы должны попытаться избежать модификации контейнера вы итерация.

Если вы видите this reference page вы увидите строку:

Ссылки и итераторы стертых элементов признаны недействительными. Другие ссылки и итераторы не затрагиваются.

Так после того, как вы называете erase итератор (s), указывающий на стертой элемент больше не действует, значит, вы больше не можете использовать, например, iter++.

+0

Ценный совет: «изменение контейнера, который вы итерируете» ... OP тщательно избегает отображения строки после итерации :) – xtofl

+0

нет модификации стирания в этом и, следовательно, я пропустил эту часть. Добавили его сейчас. – Gary