Frage

Ich habe mir die Haare gerauft, um diesen Segfault herauszufinden, und habe beschlossen, um Hilfe zu bitten.
Ich habe ein boost::multi_index Behälter, der enthält (string, string, double) und es kommt irgendwann zu einem Segfault.

Hier ist eine vereinfachte Version meines Codes:

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

Dieser Code scheint ziemlich gut zu funktionieren, aber er stürzt nur ab, wenn er auf ein bestimmtes Token trifft. (Umgekehrt stürzt er nie ab, wenn dieser nicht auf das Token trifft).
Ich denke, das passiert, weil it geht über den Bereich des Containers selbst hinaus, verstehe aber nicht, wie das passieren könnte.

Die GDB-Fehlermeldung wird angezeigt:

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

und es stürzt offensichtlich ab, wenn ich anrufe it->str1() im while-Zustand, nicht wegen des Token-Vektors.Wie kann ich das verhindern?Ich habe versucht hinzuzufügen if(it == myContainer.get<str1>().end()) break; gleich darunter *it++, hat aber nicht geholfen.
Könnte mir jemand einen Hinweis geben?
Danke schön!

War es hilfreich?

Lösung

Es gibt eine Reihe von Problemen mit Ihrem Code:

  • Es stürzt ab, wenn im Container kein entsprechendes Element vorhanden ist token[i], seit damals find kehrt zurück end(), was nicht dereferenzierbar ist.
  • Während der while Schleife it kann das Ende des Containers erreichen, und auch hier können Sie ihn nicht zurückstellen.
  • find Sie erhalten nicht das erste Element mit dem Schlüsseläquivalent zu token[i], was vermutlich das ist, was Sie wollen;verwenden lower_bound stattdessen.

Ich schlage vor, dass Sie den Code wie folgt ändern:

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

Andere Tipps

Entweder it->str1() ist null oder token[i] ist Null.

Stellen Sie sicher, dass sie nicht null sind und der Segmentierungsfehler verschwindet.

Möglicherweise möchten Sie das ersetzen while mit einem if, Beachten Sie auch, dass bei „find“ die Algorithmen „find from“ sind Hier, Wenn das Element nicht gefunden wird, wird der Iterator als Iterator des letzten Elements zurückgegeben, das möglicherweise vorhanden ist str1 als null.

Sind Sie außerdem sicher, dass Sie die Token-Zeichenfolge Zeichen für Zeichen durchlaufen und jede Übereinstimmung pro Token-Zeichen ausgeben möchten, anstatt nur eine Übereinstimmung für die gesamte Token-Zeichenfolge zu drucken? (Zumindest glaube ich, dass es sich um eine Zeichenfolge handelt, wie es Ihr Beispielcode nicht tut). Ich definiere es nicht).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top