문제

나는 이 세그폴트를 알아내기 위해 머리를 뽑고 있었고 도움을 요청하기로 결정했습니다.
나는 boost::multi_index 다음을 포함하는 컨테이너 (string, string, double) 어느 시점에서 세그폴트가 발생합니다.

내 코드의 단순화된 버전은 다음과 같습니다.

#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() while 조건에서는 토큰 벡터 때문이 아닙니다.어떻게 하면 이를 방지할 수 있나요?추가하려고했는데 if(it == myContainer.get<str1>().end()) break; 바로 아래 *it++, 하지만 도움이 되지 않았습니다.
누구든지 나에게 단서를 줄 수 있습니까?
감사합니다!

도움이 되었습니까?

해결책

코드에 여러 가지 문제가 있습니다.

  • 컨테이너에 다음과 같은 요소가 없으면 충돌이 발생합니다. token[i], 그때부터 find 보고 end(), 역참조할 수 없습니다.
  • while 고리 it 컨테이너의 끝에 도달할 수 있으며 다시 한 번 이를 존중할 수 없습니다.
  • find 다음과 동일한 키를 가진 첫 번째 요소를 얻지 못할 것입니다. token[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);
}

다른 팁

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

null이 아닌지 확인하면 분할 오류가 사라집니다.

교체를 원할 수도 있습니다. whileif, find 알고리즘이 find from인 경우에도 주의하세요. 여기, 항목이 발견되지 않으면 반복자를 마지막 요소의 반복자로 반환합니다. str1 널로.

또한 전체 토큰 문자열에 대해 하나의 일치 항목을 인쇄하는 대신 토큰 문자열 문자를 문자별로 반복하고 각 일치 항목을 토큰 문자별로 인쇄하시겠습니까?(적어도 샘플 코드에서는 문자열이라고 생각합니다. 정의하지 마세요).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top