2007年10月25日

Visual C++の標準ライブラリとcrtdbg.h

先日のcrtdbg.hを用いたメモリリークの自動検出の記事に関連して、開発中のソフトウェアに組み込んだ際に気づいた点がある。それはcrtdbg.hを#includeしなくても、関連の関数が使えてしまうことだ。それでは非常に不気味なので色々試行錯誤をしてみると、どうやらC++の標準ライブラリであるstringの#includeに問題があり、削除してみたところ、関数が使用できなくなった。そこで原因を探るべく、Visual C++のincludeディレクトリのヘッダーファイルを開いてざっと眺めてみたところ、どうやらstringから様々なヘッダーファイルに依存した結果、最終的にcrtdbg.hを#includeしてしまっているようだ。以下に依存関係を列挙しておく。

#include <string> ← #include <istream> ← #include <ostream>
← #include <ios> ← #include <xlocnum> ← #include <streambuf>
← #include <xiosbase> ← #include <xlocale> ← #include <xdebug>

最後のヘッダーファイルであるxdebugの22行目より

 #if defined(_DEBUG)
  //省略

  #include <crtdbg.h>

マクロ名_DEBUG、つまりVisual StudioのIDEでReleaseではなくDebugでビルドした場合に、問答無用でcrtdbg.hがロードされるわけである。何が問題なのかというと、crtdbg.hではグローバルスコープのnew演算子をオーバーロードしているので、仮に別途new演算子をオーバーロードしている場合にエラーとなってしまうのである。さらに他にもistreamをロードしている標準ライブラリとして、iostreamやiomanip、ios、sstreamなど多数のライブラリがロードを行っているようである。Visual C++で標準ライブラリを用いてなお且つnew演算子をオーバーロードする場合の解決策として、直感的にはxdebugの問題箇所にメスを入れれば良いが、根本的な問題はVisual C++の標準ライブラリの実装の問題なのでスマートではない。
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック