15

API呼び出しで初期化された std::map< std::string, std::string> があります。このマップを使用しようとすると、セグメンテーション違反が発生します。無効なコード、無効なコード、または問題の修正に役立つ詳細を検出するにはどうすればよいですか? コードは次のようになります。

std::map< std::string, std::string> cont;

some_func( cont ); // getting parameter by reference and initialize it, someone corrupted memory (cont) inside this function

std::cout << cont[ "some_key" ] << '\n'; // segmentation fault here, cannot access "some_key"
4

3 に答える 3

4

次の構文を使用して、(デバッグ モードでコンパイルされた) アプリケーションを起動します。

valgrind yourapp

Valgrind は、セグメンテーション違反が発生した場所のスタック バックトレースを表示します。その後、何が起こったのかを見つけて修正するのはあなた次第です。

あなたのコードでは、valgrind に関係なく、 cont[ "some_key" ]segfault の原因として最も可能性が高いのは、戻り値がワイルド ポインターであるか、まったく初期化されていないことです。その場合、同様にアクセスしようとするとcont["some_key"][0]、セグメンテーション違反も発生します。

別のアイデア: マップ内の文字列キーはどうですか? それらのいくつかが、キーとして使用される文字列のデータ部分を静かに (例外なく) 割り当てることができなかった可能性はありますか? std::map はハッシュ テーブルではなく、順序付けられたコンテナーです。キーを検索するときに、他のキーにアクセスする必要があり、そこで何かが起こる可能性があります。マップ内のすべてのキーを反復処理してコンテンツを表示できることを確認するには (「some_key」で特に問題が発生するかどうか、またはマップ内の何もアクセスできないかどうかを確認します。

プログラムが順序付けを必要としない場合は、 unordered_map を試して動作が同じかどうかを確認することもできます。

于 2010-04-21T14:32:33.440 に答える
3

一般に、その行がどのようにセグメンテーション違反を生成しているのかわかりません。ブラケット演算子は常にstd :: stringを返し(必要に応じて空の文字列を作成します)、印刷には常に有効である必要があります。

代わりに、表示される呼び出しスタックが実行する次の行を指していて、some_funcで停止している可能性はありますか?そのためのコードが表示されないため、問題が発生している可能性があるかどうかはわかりません。

またはsome_func、char *(temp std :: stringを呼び出す)を使用してマップ内の文字列を初期化しますか?しばらくの間「動作する可能性がある」無効な文字列をマップに導入している可能性がありますが、some_funcが返されると、印刷とうまく相互作用しません。

于 2010-04-21T15:01:06.567 に答える
0

valgrind に加えて、問題に集中するためにデバッガーの使用を試すことができます。

行にブレークポイントを設定し、有効な参照some_func(cont)かどうかを調べます。cont

さらに、cont["some_key"]some_key が存在しない場合に何が返されるかを検討しましたか?

于 2010-04-21T14:35:49.593 に答える