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

文書翻訳 文書翻訳
文書番号: 194550 - 対象製品
この記事は、以前は次の 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;
   }
				

プロパティ

文書番号: 194550 - 最終更新日: 2006年2月6日 - リビジョン: 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
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com