SIGSEGV, mentre ad esplorare boost::multi_index
-
11-12-2019 - |
Domanda
Sto tirando fuori i miei capelli per capire questo segfault e ha deciso di chiedere aiuto.
Ho un boost::multi_index
contenitore, che contiene (string, string, double)
e colpisce un segfault a un certo punto.
Qui è una versione semplificata del mio codice:
#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++;
}
Questo codice sembra funziona abbastanza bene, ma si blocca solo quando colpisce alcune specifiche token.(Opposta a parlare, non si blocca quando questo non soddisfa il token).
Credo che questo accade perché it
va al di sopra del range di contenitore stesso, ma non riesco a capire come si potrebbe eventualmente accadere.
GDB visualizzazione del messaggio di errore:
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 ovviamente si blocca quando mi chiamano it->str1()
mentre la condizione, non a causa del token vettoriale.Come posso evitare questo?Ho provato ad aggiungere if(it == myContainer.get<str1>().end()) break;
sotto a destra *it++
, ma non ha aiutato.
Qualcuno può darmi qualche indizio?
Grazie!
Soluzione
Ci sono un certo numero di problemi con il tuo codice:
- Andrà in crash se non c'è nessun elemento nel contenitore equivalente a
token[i]
, da allorafind
restituisceend()
, che non è dereferenceable. - Durante il
while
loopit
può raggiungere la fine del contenitore, e ancora non sarà in grado di deferenza esso. find
non si ottiene il primo elemento con il tasto equivalente atoken[i]
, che è presumibilmente quello che vuoi;utilizzarelower_bound
invece.
Ti suggerisco di modificare il codice come segue:
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);
}
Altri suggerimenti
it->str1()
è nullo o token[i]
è nullo.
Assicurarsi che non siano null e l'errore di segmentazione andrà via.
Potrebbe voler sostituire il while
con un if
, essere consapevole che se trovare gli algoritmi trovano da Qui , se l'elemento non viene trovato restituisce l'iteratore come iteratore dell'ultimo elemento, che potrebbe avere str1
come null.
Inoltre sei sicuro di voler Iteratore sul carattere della stringa del token per personaggio e stampare ogni corrispondenza per carattere token anziché semplicemente stampare una partita per l'intera stringa di token? (Almeno penso che sia una stringa, come il tuo campioneIl codice non lo definisce).