現在オフラインです。再接続するためにインターネットの接続を待っています

[FIX] Visual C++ でメモリを重複して解放するとアプリケーション エラーが発生することがある

この記事は、以前は次の ID で公開されていました: JP194550
現象
メモリを重複して解放するとアプリケーション エラーが発生することがあります。

: この問題は、malloc 関数で確保した領域を free 関数で複数回解放する場合と、new 演算子で確保した領域を delete 演算子で複数回削除する場合のいずれにも該当します。
原因
ヒープを制御する構造体が、最初の free() 関数の呼び出し後に変更されています。このため、これ以降の free() 関数の呼び出しが正常に実行されません。
解決方法
同じポインタに対して free や delete を複数回実行しないようにします。これを防ぐ 1 つの方法は、free や delete を呼び出した後、ポインタに null を代入することです。引数として null ポインタが渡された場合、delete や free 関数は何も行わずに制御を返します。この方法は、メモリ上の同じ場所を参照している複数のポインタに対して free 関数や delete が呼び出される場合には適用できません。

サードパーティ製のアプリケーションでこの問題が発生しているユーザーをサポートするため、マイクロソフトは、新しい C ランタイム ライブラリ DLL である Msvcrt.dll をリリースしました。この DLL は 2 つのヒープ マネージャを実装しており、1 つは Visual C++ 5 互換のヒープ マネージャ、もう 1 つは Visual C++ 6 互換のヒープ マネージャです。この DLL は、アプリケーションをビルドした Visual C++ のバージョンを検出し、そのアプリケーションに対して適切なヒープ マネージャを使用します。このバージョンが 6.0 以降の場合は Visual C++ 6 互換のヒープ マネージャが使用され、6.0 より前のバージョンの場合は Visual C++ 5 互換のヒープが使用されます。

Visual Studio 6.0 のユーザーは、最新の Microsoft Visual Studio Service Pack をインストールすることで、この新しい msvcrt.dll を入手できます。それ以外のユーザーは、Microsoft Libraries Update をインストールする必要があります。
状況
マイクロソフトでは、この問題をこの資料の対象製品として記載されているマイクロソフト製品の問題として認識しています。
この問題は、Visual Studio 6.0 Service Pack 3 で修正済みです。 Visual Studio の Service Pack の詳細については、次の「サポート技術情報」 (Microsoft Knowledge Base) の資料を参照してください。

194022 Visual Studio 6.0 Service Pack の内容と入手先

194295 Visual Studio Service Pack がインストール済みか確認する方法
詳細
メモリを重複して解放した場合に発生する現象は予測できません。

以下のサンプル コードのリリース ビルドは、Visual C++ 6.0 でビルドした場合はアプリケーション エラーが発生しますが、Visual C++ 5.0 でビルドした場合はアプリケーション エラーは発生しません。

デバッグ ビルドでは、Visual C++ 6.0 と Visual C++ 5.0 のどちらでビルドした場合でも、ASSERT が呼び出されます。
   Debug Assertion Failed!				

SBH (Small Block Heap) の状態は常に流動的であることに注意することが重要です。このため、デバッグ ビルドでアサーションが発生しなくてもリリース ビルドでアプリケーション エラーが発生する場合がありえます。

Visual C++ 6.0 のリリース ビルドでは、Visual C++ 5.0 の場合よりも、メモリの解放処理の重複による影響が顕著です。Visual C++ 5.0 でビルドした場合、下記の例のように free 関数を不適切に呼び出しても実害のない場合があります。元の場所よりもかなり離れた場所で free() 関数が呼び出された場合は、アプリケーション エラーが発生する可能性があります。メモリが破損する可能性が高くなります。

サンプル コード

   // Compile options for Release builds /c   // Compile options for Debug builds /c /Zi   #include <malloc.h>   int main(int argc, char* argv[])   {      char *pChar1 = (char *)malloc(10*sizeof(char));      char *pChar2 = (char *)malloc(10*sizeof(char));      free(pChar1);      free(pChar1);      return 0;   }				
msvcrt.dll kbVS600sp2
プロパティ

文書番号:194550 - 最終更新日: 02/06/2006 08:26:00 - リビジョン: 3.0

Microsoft Visual C++ 6.0 Enterprise Edition, Microsoft Visual C++ 6.0 Professional Edition, Microsoft Visual C++, 32-bit Learning Edition 6.0

  • kberrmsg kbbug kbfix kbcrt kbqfe kbcode kbvs600sp2fix kbvs600sp3fix KB194550
フィードバック