Pergunta

Eu fui puxando meu cabelo para descobrir esse segfault e decidiu pedir ajuda.
Eu tenho um boost::multi_index recipiente que contém (string, string, double) e ele acerta um segfault em algum ponto.

Aqui está uma versão simplificada do meu código:

#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++;
}

Este código parece funcionar muito bem, mas falha somente quando ele atinge alguns específico do token.(Ao contrário de falar, nunca falha quando este não atender o token).
Eu acho que isso acontece porque it vai acima do intervalo de recipiente próprio, mas não entende como é que isso poderia acontecer.

GDB mensagem de erro é exibida:

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 ...

e isso, obviamente, falha quando eu chamo it->str1() enquanto condição, não porque o token de vetor.Como posso evitar isso?Eu tentei adicionar if(it == myContainer.get<str1>().end()) break; logo abaixo *it++, mas não ajuda.
Que alguém poderia me dar alguma pista?
Obrigado!

Foi útil?

Solução

Há uma série de problemas com o seu código:

  • Ele irá falhar se não existir nenhum elemento do contêiner equivalente a token[i], desde então find retorna end(), que não é dereferenceable.
  • Durante o while loop it pode chegar o final do recipiente, e, novamente, você não será capaz de deferência-lo.
  • find não obter o primeiro elemento com chave equivalente a token[i], que é provavelmente o que você quer;utilização lower_bound em vez disso.

Eu sugiro que você altere o código da seguinte maneira:

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);
}

Outras dicas

Ou it->str1() é nulo ou token[i] é nulo.

Certifique-se de que eles não são nulos e a falha de segmentação, vai embora.

Você pode querer substituir o while com um if, também estar ciente de que se encontra é encontrar a partir de algoritmos aqui, se o item não for encontrado, retorna o iterador como o iterador de o último elemento, o que pode ter str1 como null.

Também tem certeza de que deseja iterador sobre o token de cadeia de caractere por caractere e impressão de cada jogo por token de caracteres ao invés de incluir somente a impressão de um jogo para toda a cadeia de token ?(pelo menos eu acho que é uma seqüência de caracteres, como o código de exemplo não a definem).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top