2012-08-31 2 views
0

valgrind를 실행할 때 크기가 4 인 잘못된 단일 읽기 오류를 표시하는 단일 스레드 프로그램이 있습니다. I는 해당 프로그램 바와 같이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

왓슨 (Watson)과 겉으로보기에는 '무언가'입니다. 컨테이너와 관련된 모든 코드를 보여주십시오 : – xtofl

답변

1

는 말을 열심히 그래서 당신은 전체 코드를 표시하지 않습니다,하지만 당신은 당신이 이상 반복되는 컨테이너를 수정하지 않도록 노력해야한다.

당신은 당신이 줄 알 this reference page 표시되는 경우 삭제 된 요소에

참조 및 반복자가 무효화됩니다. 다른 참조 및 반복기는 영향을받지 않습니다.

그래서 당신은 erase를 호출 한 후 삭제 요소를 가리키는 반복자 (들)을 더 이상 사용할 수 없습니다 즉, 더 이상 유효하지 예를 들어, iter++.

+0

귀중한 힌트 : "반복하는 컨테이너 수정하기"... OP는 반복 후 우리에게 라인을 보여주는 것을 조심스럽게 피합니다 :) – xtofl

+0

그 안에는 지우기 수정이 없습니다 루프 따라서 나는 그 부분을 생략했다. 지금 추가했습니다. – Gary

관련 문제