SIGSEGV, tout en explorant les boost::multi_index
-
11-12-2019 - |
Question
J'ai été m'arracher les cheveux pour comprendre cette erreur et a décidé de demander de l'aide.
J'ai un boost::multi_index
le conteneur qui contient (string, string, double)
et il frappe une erreur de segmentation à un certain point.
Voici une version simplifiée de mon code:
#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++;
}
Ce code semble plutôt bien, mais il se bloque uniquement quand il frappe certains jeton.(À l'opposé de parler, il ne se bloque lorsque cela ne veut pas rencontrer le jeton).
Je suppose que cela se produit parce que it
passe au dessus de la gamme de conteneur lui-même, mais ne comprends pas comment cela pourrait bien arriver.
GDB message d'erreur s'affiche:
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 ...
et il est évident qu'elle se bloque quand je l'appelle it->str1()
en tout état, non pas parce que le jeton de vecteur.Comment puis-je éviter cela?J'ai essayé d'ajouter if(it == myContainer.get<str1>().end()) break;
ci-dessous à droite *it++
, mais qui ne l'a pas aider.
Quelqu'un pourrait-il me donner quelques indices?
Merci!!!!
La solution
Il y a un certain nombre de problèmes avec votre code:
- Il va planter si il n'y a aucun élément dans le conteneur équivalent à
token[i]
, depuisfind
retourneend()
, qui n'est pas dereferenceable. - Au cours de la
while
boucleit
peut atteindre à la fin du conteneur, et de nouveau, vous ne serez pas en mesure de déférence elle. find
vous n'obtiendrez pas le premier élément avec la clé équivalente àtoken[i]
, ce qui est probablement ce que vous voulez;utilisationlower_bound
au lieu de cela.
Je vous suggère de modifier le code comme suit:
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);
}
Autres conseils
Soit it->str1()
est null ou token[i]
est null.
S'assurer qu'ils ne sont pas null et le segmentation fault aller loin.
Vous pouvez remplacer la while
avec un if
, également être conscients que si la trouvaille est d'algorithmes de trouver de ici, si l'élément n'est pas trouvé, il renvoie l'itérateur comme l'itérateur sur le dernier, ce qui peut avoir str1
comme null.
Aussi êtes-vous sûr que vous voulez itérateur sur le jeton de la chaîne caractère par caractère et imprimer chaque match par jeton personnage plutôt que de simplement l'impression d'un match pour l'ensemble de la chaîne de jeton ?(au moins je pense que c'est une chaîne, comme dans votre exemple de code ne définit pas elle).