タダでソフト開発の生産性と品質を上げる方法(9):メモリリークを一瞬で見つける「Valgrind」(その2)山浦恒央の“くみこみ”な話(99)(3/3 ページ)

» 2017年10月11日 10時00分 公開
前のページへ 1|2|3       

3.3 領域外書き込み

 「領域外書き込み」とは、確保した領域外に値を書き込むことを言います。いわゆるメモリ破壊ですね。領域外(別の変数)に書き込むと、別変数を読み出した場合、変数値が破壊され、不可解な現象が起こる原因となります(バグの現象に規則性がないため、単純なバグながら、検出するのは非常に大変です)。リスト3で、考えてみましょう。

#include<stdlib.h>
int main(){
	char *str;
	str = (char*)malloc(5);
	str[5] = 'b';
	free(str);
	return 0;
}
リスト3 領域外の書き込み例

 リスト3は、char型で5バイト分をmalloc関数を使って確保しました。つまり、変数strは、0〜4番地にアクセスできます。しかし、5行目では、strが範囲外の5番地に「b」を書き込んでいます。典型的な領域外アクセスですね。valgrindを実行すると、図3のようなエラーメッセージが出ます。

図3 図3 リスト3実行時のログ

 3行目に「Invalid write of size 1」と出ており、「1バイト誤って書き込んでいます」の意味です。例えば、5行目を「str[4] = 'b';」に変更すると、Valgrindのエラーメッセージはなくなります。

 リスト2、3のように短い例題では、メモリのアクセス例外はすぐに発見できますが、扱う範囲が増えると、分かりにくくなります。Valgrindをデバッグ時に使用し、見つけにくいバグを機械的に広範囲で検出すると、時間と労力の節約になります。

4.まとめ

 今回の内容を以下にまとめます。

  • Valgrindは、動的解析ツールである
  • Valgrindは、未初期化変数を検出できる
  • Valgrindは、領域外の読み込みや書き込みを検出できる
  • Valgrindは、うっかりミスを防止上、デバッグ時に有効なツールである

5.終わりに

 エンジニアは、決まった時間内に最大限の成果物を出力することが重要です。そのためには、単純作業は極力減らすべきでしょう。Valgrindは、プログラマーが見落としやすいメモリ関連のバグを瞬時に検出するツールで、デバッグ時に有効です。この類のツールは有償、無償問わず数多く出回っていますので、調べてみるといいでしょう。

参考文献

[1]「モダンC言語プログラミング」(花井志生、2013、KADOKAWA/アスキーメディアワークス社)

[2]「デバッグの理論と実践 なぜプログラムはうまく動かないのか」(Andreas Zeller他、2012、オライリージャパン)


【 筆者紹介 】
山浦 恒央(やまうら つねお)

東海大学 大学院 組込み技術研究科 非常勤講師(工学博士)


1977年、日立ソフトウェアエンジニアリングに入社、2006年より、東海大学情報理工学部ソフトウェア開発工学科助教授、2007年より、同大学大学院組込み技術研究科准教授、2016年より非常勤講師。

主な著書・訳書は、「Advances in Computers」 (Academic Press社、共著)、「ピープルウエア 第2版」「ソフトウェアテスト技法」「実践的プログラムテスト入門」「デスマーチ 第2版」「ソフトウエア開発プロフェッショナル」(以上、日経BP社、共訳)、「ソフトウエア開発 55の真実と10のウソ」「初めて学ぶソフトウエアメトリクス」(以上、日経BP社、翻訳)。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.