6
4

More than 3 years have passed since last update.

C++でメモリリークに困った時の対処法。

Posted at

概要

C++で開発をするときに、メモリリークを確認しているが、どこでリークしているのかわからない。
そういうときに、g++の標準装備でどこがメモリリークしているかをチェックできます。

状況説明

簡単な例でいうと、

test.cpp
int main() {
  int *a = new int[10];
}

このようにnew演算子をもちいてメモリを確保しているのにも関わらず、delete a
を書き忘れている。(これは見ただけですぐわかるメモリリークだが、実際はコード構造が複雑で、どこでリークしているかわからないこともしばしば。)

これを実行すると、aとして確保されたメモリが解放されず、メモリリークとなる。コンパイルエラー、プログラム実行時のエラーいずれも起こらない。

対処法

AddressSanitizer というツールを使う

コンパイルオプションを付け加えるだけでメモリリークを検出してくれるので、便利です。

実際にコンパイルする時のコマンドは、
g++ -fsanitize=address -fno-omit-frame-pointer -g test.cpp
です。その後にプログラムを./a.outで走らせると、
Screen Shot 2020-03-14 at 20.28.11.png

となります。

#0 0x7fa3f0a33618 in operator new[](unsigned long)
#1 0x5604a079d7fb in main /from_local/test.cpp:2

のところを見ると、test.cpp の2行目でメモリをnew演算子で確保したところでメモリリークしていることが確認できます。
もう少し複雑に絡み合った構成でも、このように的確にメモリリークの原因を出力してくれます。

まとめ

今回はC++での開発時にやっかいな問題であるメモリリークの解消方法の1つとして、AddressSanitizerを用いた例を紹介しました。
もしメモリリークに悩んでいる時があったら、コンパイルオプションを使って簡単に確認できるのでぜひ試して見てください。

おわり。

6
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4