2016-06-30 9 views
-1

현재 개발중인 프로그램의 워크 플로를 제어하려고합니다. 이렇게하려면 map< unsigned int, list < unsigned int > >에서 첫 번째 키는 ID가되고 두 ​​번째 (목록)는 모든 작업을 올바르게 끝내는 데 사용됩니다. 나는이 목록에서 사용하는 유일한 작업은 다음과 같습니다my_list.push_back()이 잘못된 할당 오류.

myMap[iD].size() 
myMap[iD].push_back(foo) <- (foo is an unsigned int) 
for (std::list<unsigned int>::iterator it=myMap[iD].begin(); it != myMap[iD].end(); ++it){ 
myMap[iD].erase(it) 
} 

내지도의 길이는 1452 개 요소로 성장할 수 있고 내가를 실행하면 각 요소의 목록 크기는 ~ 5000

1000 순서에서 할 수 있습니다 프로그램에서 가끔 세분화 오류가 발생하고 잘못된 할당 오류가 발생합니다. 내 생각 엔이 이유는 push_back에서 온 것입니다.

  • 요소를 뒤로 밀지 않으면 프로그램이 올바르게 작동합니다.
  • 새 요소의 저장소는 컨테이너의 할당자를 사용하여 할당됩니다.이 경우 기본 할당자인 할당 요청이 성공하지 못한 경우 bad_alloc이 throw됩니다. http://www.cplusplus.com/reference/list/list/push_back/

내가지도를 사용하는 곳이 코드의 일부에 불과합니다 :

if (FOO != 0){ 
    if (PID != 0){ 

     if (myMap.size() + 5 < myMap.max_size()){ 
      if (myMap[PID].size() > 1000) myMap[PID].pop_front(); 
      myMap[PID].push_back(EVENTVALUE); 
     } 

    } 
} else { 
    if (PID != 0 and foo2 != 0 and myMap.find(PID) != myMap.end()) { 
     for (std::list<unsigned int>::iterator it=myMap[PID].begin(); it != myMap[PID].end(); ++it){ 
      if (*it == foo2){ 
       cout << " erasing pid: " << PID << endl; 
       myMap[PID].erase(it); 
       if (myMap[PID].size() == 0) myMap.erase(PID); 
       break; 
      } 

     } 
    } 
} 

가 나는 또한 도구 Valgrind의를 사용하는 시도하고 이것이 출력 :

==4092== Invalid read of size 8 
==4092== at 0x4F09EB8: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120) 
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393) 
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905) 
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743) 
==4092== by 0x404F49: main (foo.cc:3159) 
==4092== Address 0x6157d08 is 0 bytes after a block of size 8 alloc'd 
==4092== at 0x4C29670: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4092== by 0x40DB77: allocate (new_allocator.h:104) 
==4092== by 0x40DB77: _M_allocate (stl_vector.h:168) 
==4092== by 0x40DB77: void std::vector<std::string, std::allocator<std::string> >::_M_emplace_back_aux<std::string>(std::string&&) (vector.tcc:404) 
==4092== by 0x408F3E: push_back (stl_vector.h:920) 
==4092== by 0x408F3E: split(std::string const&, char, int) (foo.cc:416) 
==4092== by 0x41577F: lustreLine::toPRV(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1741) 
==4092== by 0x404F49: main (foo.cc:3159) 
==4092== 
==4092== Invalid read of size 4 
==4092== at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120) 
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393) 
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905) 
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (foo.cc:1743) 
==4092== by 0x404F49: main (foo.cc:3159) 
==4092== Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd 
==4092== 
==4092== 
==4092== Process terminating with default action of signal 11 (SIGSEGV) 
==4092== Access not within mapped region at address 0xFFFFFFFFFFFFFFF8 
==4092== at 0x4F09EBB: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) (in /usr/lib64/libstdc++.so.6.0.21) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (new_allocator.h:120) 
==4092== by 0x40CCA9: _S_construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:254) 
==4092== by 0x40CCA9: construct<std::basic_string<char>, const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&> (alloc_traits.h:393) 
==4092== by 0x40CCA9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:905) 
==4092== by 0x4157AC: foo::foo(std::basic_ofstream<char, std::char_traits<char> >&) (fpp.cc:1743) 
==4092== by 0x404F49: main (foo.cc:3159) 
==4092== If you believe this happened as a result of a stack 
==4092== overflow in your program's main thread (unlikely but 
==4092== possible), you can try to increase the size of the 
==4092== main thread stack using the --main-stacksize= flag. 
==4092== The main thread stack size used in this run was 8388608. 

[...]

(더 많은 출력이 필요한 경우에만 요청하십시오)

개인 정보 보호를 위해 변수 이름을 변경해야했습니다. 문제가되지 않기를 바랍니다.

독서에 감사드립니다. 좋은 하루 되세요!

+0

이게 뭐야 : myMap.size() [PID]'? –

+0

oups, 내가 잘못 복사 한 변수 이름을 변경했을 때 @AdrianRoman을 편집하겠습니다. – tknbr

답변

7

첫 번째 for 루프는 잘못 반복자 iterase 각 호출 후 무효가됩니다

for (std::list<unsigned int>::iterator it=myMap[iD].begin(); it != myMap[iD].end(); ++it){ 
    myMap[iD].erase(it); 
} 

때문이다.

당신은 그것을 다시 쓸 수있다 : 단지

myMap[iD].clear(); 

이 당신이 유사한 실수를 귀하의 질문에 for 루프 다른 것 같다 더 나은 아직

for (auto it = myMap[iD].begin(); it != myMap[iD].end();) 
{ 
    it = myMap[iD].erase(it); 
} 

또는 - 일반적으로 당신 패턴을 사용해야합니다 :

for (auto it = foo.begin(); it != foo.end();) 
{ 
    if (some_condition) 
     it = foo.erase(it); // erase map entry, update iterator 
    else 
     ++it;     // bump iterator 
} 

의 예제를 참조하십시오..

+1

감사합니다! 그게 내 문제를 해결, 대답 accpeted : P는 – tknbr