Pregunta

Me estuve arrancando el pelo para descubrir este error de segmentación y decidí pedir ayuda.
tengo un boost::multi_index contenedor, que contiene (string, string, double) y sufre un fallo de segmento en algún momento.

Aquí hay una versión simplificada de mi 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 bastante bien, pero falla solo cuando alcanza algún token específico (por el contrario, nunca falla cuando no cumple con el token).
Supongo que esto sucede porque it va por encima del rango del contenedor en sí, pero no entiendo cómo podría suceder.

Aparece un mensaje de error de 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 ...

y obviamente falla cuando llamo it->str1() en condición while, no debido al vector del token.¿Cómo puedo prevenir esto?Intenté agregar if(it == myContainer.get<str1>().end()) break; justo debajo *it++, pero no ayudó.
¿Alguien podría darme alguna pista?
¡Gracias!

¿Fue útil?

Solución

Hay una serie de problemas con su código:

  • Se bloqueará si no hay ningún elemento en el contenedor equivalente a token[i], Desde entonces find devoluciones end(), que no es desreferenciable.
  • Durante el while bucle it Puede llegar al final del contenedor y nuevamente no podrá deferenciarlo.
  • find no obtendrá el primer elemento con clave equivalente a token[i], que presumiblemente es lo que quieres;usar lower_bound en cambio.

Le sugiero que cambie el código de la siguiente manera:

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

Otros consejos

Cualquiera it->str1() es nulo o token[i] es nulo.

Asegúrese de que no sean nulos y el error de segmentación desaparecerá.

Es posible que desee reemplazar el while con un if, también tenga en cuenta que si find son algoritmos que encuentran desde aquí, si no se encuentra el elemento, devuelve el iterador como el iterador del último elemento, que puede tener str1 como nulo.

Además, ¿está seguro de que desea iterar sobre la cadena del token carácter por carácter e imprimir cada coincidencia por carácter del token en lugar de simplemente imprimir una coincidencia para toda la cadena del token? (Al menos creo que es una cadena, como lo hace su código de muestra). no definirlo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top