pImplイディオムを使っているところでメモリリークしていた。調べてみると、pImplクラスの解放をauto_ptrに任せていたのが原因らしい。orz
// Hoge.h class Hoge { Hoge(); private: struct pImpl; std::auto_ptr<pImpl> impl; }; // Hoge.cpp struct Hoge::pImpl { ~pImpl() { std::cout << "Destructor" << std::endl; } }; Hoge::Hoge() : impl(new pImpl){}
不完全クラスのdeleteは未定義なため*1、上記のような実装を行うと auto_ptr は pImpl のデストラクタを適切に呼び出してくれず、メモリリークが生じる事がある。
こういう用途に使う場合は boost::shared_ptr を使うと安全です。
pimplイディオムを語る
—
ありえるえりあ
で紹介されているコードでも、同じ問題が出そう。
あれ、VC8だとちゃんとデストラクタが呼ばれるな……なんでだろ。……どうやら Hoge のデストラクタが定義されていると、リンク時にうまいことやってくれる、っぽい?
// Hoge.h class Hoge { Hoge(); ~Hoge(); // ここを追加 private: struct pImpl; std::auto_ptr<pImpl> impl; }; // Hoge.cpp struct Hoge::pImpl { ~pImpl() { std::cout << "Destructor" << std::endl; } }; Hoge::Hoge() : impl(new pImpl){} Hoge::~Hoge() {} // ここを追加
デストラクタをインラインにするとうまくいかなくなる模様。よくわからないなぁ。なお bcc5.6.4 では、上記のようにしてもやっぱり駄目なようです。
追記
キーワード変えてぐぐったら超がいしゅつ(なぜか変換ry)でした><
shared_ptrからpimplのデストラクタ呼び出し - C・C++ - 教えて!goo
bccでうまくいかないのはバグかなー。