質問

私はこのSegfaultを把握し、いくつかの助けを求めることを決めました。
boost::multi_indexコンテナがあり、(string, string, double)を含み、ある時点でSegfaultにヒットします。

これは私のコードの単純化されたバージョンです:

#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()を呼び出すと明らかにクラッシュします。どうやってこれを防ぐことができますか? if(it == myContainer.get<str1>().end()) break;の下の*it++を追加しようとしましたが、役に立ちませんでした。
誰かが私にいくつかの手がかりを与えますか?
ありがとうございました!

役に立ちましたか?

解決

あなたのコードには多くの問題があります:

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

他のヒント

it->str1()はNULLまたはtoken[i]のいずれかがNULLです。

それらがnullでないことを確認し、セグメンテーション障害が消えます。

whileifに置き換えることもできます。nofollow ">ここ、アイテムが見つからない場合、それは最後の要素のイテレータとしてイテレータを返します。これは、nullとしてstr1を持つことがあります。

また、トークン文字列全体を印刷するだけではなく、トークン文字列文字の上にイテレータを文字列文字でイテレータに印刷しますか?(少なくとも私はあなたのサンプルとして、それが文字列であると思います。コードはそれを定義しません)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top