2012-03-11 5 views
0

나는이 세그 폴트를 알아 내기 위해 머리카락을 뽑아 내고 도움을 요청하기로 결정했다.
나는 (string, string, double)을 포함하는 boost::multi_index 컨테이너가 있으며 어느 시점에서 segfault에 도달합니다. 여기 SIGSEGV 탐색하면서 boost :: multi_index

내 코드의 단순화 된 버전입니다 :

#include<iostream> 
.... 

// mySet is a multi_index container which contains <(string str1), (string str2), (double val)> 

typedef mySet::index<str1>::type set_by_str1; 

... 

for(unsigned int i=0; i < token.size(); ++i) 
{ 
    set_by_str1::iteration it = myContainer.get<str1>().find(token[i]); 
    while(it->str1() == token[i]) 
    { 
     cout << it->str1() << ", " << it->str2() << ", " << it->val << endl; 
    } 
    *it++; 
} 

이 코드는 꽤 잘 작동하는 것 같다,하지만 일부 특정 토큰을 칠 때 그것은 단지 충돌 (반대로이 충족되지 않는 경우는 충돌하지, 말하기. 토큰).
it은 컨테이너 자체의 범위를 넘기 때문에 발생할 수있는 일이지만 어떻게 될지 이해하지 못하기 때문에 이런 일이 발생합니다.

GDB 오류 메시지가 표시됩니다 :

Program received signal SIGSEGV, Segmentation fault. 
0x08052e83 in std::string::size (this=0x806e190) at /usr/include/c++/4.4/bits/basic_string.h:629 
629  { return _M_rep()->_M_length; } 

(gdb) bactrace full 
#0 0x08052e83 in std::string::size (this=0x806e190) at /usr/include/c++/4.4/bits/basic_string.h:629 
No locals. 
#1 0x08050475 in std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__os=..., __str=...) 
    at /usr/include/c++/4.4/bits/basic_string.h:2503 
No locals. 
#2 0x0804e4e0 in MyClass:MyFunction (this=0xbffff534) at src/MyCode.cpp:353 (This is where while condition exists) 
... dump of HUGE trace for multi_index ... 

내가 때문이 아니라 토큰 벡터의, 동안 상태 it->str1()를 호출 할 때 분명히 충돌합니다. 이 문제를 어떻게 방지 할 수 있습니까? if(it == myContainer.get<str1>().end()) break; 바로 아래에 *it++을 추가하려했지만 도움이되지 않았습니다.
아무도 내게 어떤 단서를 주겠습니까?
감사합니다.

답변

0

코드에 문제가 있습니다 :

  • token[i]에 컨테이너 동등한 어떤 요소가 존재하지 않는 경우 그것은, 충돌합니다 find 그 이후 반환 end(), dereferenceable 없습니다.
  • while 루프 it 중에는 컨테이너의 끝까지 도달 할 수 있으며 다시는이를 존중할 수 없습니다.
  • findtoken[i]에 해당하는 키가있는 첫 번째 요소를 얻지 못합니다. 이는 아마도 원하는 것일 것입니다. 대신 lower_bound을 사용하십시오.

나는 다음과 같이 코드를 변경 제안 :

pair<set_by_str1::iterator, set_by_str1::iterator> p = 
    myContainer.get<str1>().equal_range(token[i]); 

while(p.first!=p.second) 
{ 
    cout << p.first->str1() << ", " << p.first->str2() << ", " 
     << p.first->val << endl; 
    ++(p.first); 
} 
0

it->str1()이 null이거나 token[i]이 null입니다.

null이 아니고 세그먼트 화 오류가 없어지는지 확인하십시오.

항목이 그것으로 str1을 가질 수있는 마지막 요소의 반복자로서 반복자를 반환 찾을 수없는 경우 당신은 또한, ifwhile 교체 발견 인 경우 알고리즘, here에서 찾을 수 있음을 인식 할 수 있습니다

없는.

토큰 문자열에 대해 문자 단위로 반복자를 만들고 전체 토큰 문자열에 대해 하나의 일치를 인쇄하는 대신 각 토큰마다 일치하는 내용을 인쇄 하시겠습니까? (최소한 문자열이라고 생각합니다. 샘플 코드는 그것을 정의하지 않습니다.)