web-dev-qa-db-ja.com

Valgrindを使用してセグメンテーション違反の詳細を検出する方法は?

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"
12

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

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

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

3
Mark B

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

valgrind yourapp

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

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

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

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

3
kriss

Valgrindに加えて、問題に焦点を合わせるためにデバッガーを使用してみることができます。

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

また、何を考えましたかcont["some_key"] some_keyが存在しない場合、戻ってきますか?

0
Tom