0

私はこの segfault を理解するために髪を引っ張ってきましたが、助けを求めることにしました。コンテナーがあり、
ある時点で segfault が発生します。boost::multi_index(string, string, double)

これが私のコードの簡略版です:

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

このコードはかなりうまく機能しているように見えますが、特定のトークンにヒットした場合にのみクラッシュします (逆に言えば、これがトークンに一致しない場合はクラッシュしません)。これは、コンテナ自体の範囲を超えて
いるために発生すると思いますが、どのように発生する可能性があるのか​​ わかりません。it

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

it->str1()トークンベクトルが原因ではなく、 while 条件を呼び出すと明らかにクラッシュします。どうすればこれを防ぐことができますか? if(it == myContainer.get<str1>().end()) break;すぐ下に追加しようとしまし*it++たが、役に立ちませんでした。
誰か手がかりを教えてくれませんか?
ありがとうございました!

4

2 に答える 2

0

コードにはいくつかの問題があります。

  • コンテナにに相当する要素がない場合はクラッシュします。それtoken[i]以降は、参照解除できないをfind返します。end()
  • whileループ中にitコンテナの最後に到達する可能性があり、これもまた、それを尊重することはできません。
  • findと同等のキーを持つ最初の要素を取得しませんtoken[i]。これはおそらくあなたが望むものです。lower_bound代わりに使用してください。

次のようにコードを変更することをお勧めします。

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);
}
于 2012-03-11T14:50:32.420 に答える
0

nullit->str1()または token[i]null です。

それらが null でないことを確認してください。セグメンテーション違反は解消されます。

また、find がアルゴリズム find from hereの場合、項目が見つからない場合は最後の要素の反復子として反復子を返すことに注意whileしてください。ifstr1

また、トークン文字列全体に対して 1 つの一致を出力するだけでなく、トークン文字列を 1 文字ずつ反復処理し、トークン文字ごとに各一致を出力したいですか? (少なくとも、サンプル コードがそうであるように、文字列だと思います。定義しないでください)。

于 2012-03-11T06:16:50.200 に答える