1. ホーム
  2. c#

解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.

2022-01-29 04:32:29

質問

私は、メインのC#アプリケーションにいくつかの機能を提供するC++のDLLを持っています。 ここでは、ファイルを読み込んでメモリにロードし、ロードしたデータへのポインタやメモリブロックの数などの情報をC#に返そうとしています。Dllは正常にファイルをメモリに読み込みますが、メインアプリケーションに戻ると、ヒープ破壊(Critical error detected c0000374)のためにプログラムがクラッシュします。

このコードは非常にシンプルでわかりやすく、以前にも同じようなことを問題なく行ったことがありますが、今回の問題の原因はわかりませんでした。コードは以下の通りです。

C++のMyDllです。

typedef unsigned long         U32;

extern "C" __declspec(dllexport) int ReadFile(LPSTR Path, U32** DataPtr, U32* Count)
{
   FILE *fp;
   U32 *Data;
   CString tempStr(Path);
   long fSize;

   if(!(fp = fopen(tempStr, "rb"))) {
    return 0;
   }

   // Obtain File Size;
   fseek(fp, 0, SEEK_END);
   fSize =  ftell(fp);
   rewind(fp);

   Data = (U32 *)GlobalAlloc(0, fSize);
   if(Data == NULL) {
            fclose(fp);
            return -1;
    }

    // Copy file into the buffer.
        if(!(*Count = fread(Data, sizeof(U32), fSize / sizeof(U32), fp))) {
           fclose(fp);
           free(Data);
           return -2;
        }

   *DataPtr = (U32 *)Data;
       return 1;
}

C#のアプリケーションです。

        [DllImport(@"MyDll.dll", CallingConvention= CallingConvention.Cdecl)]
    private static extern int ReadFile([MarshalAs(UnmanagedType.LPStr)]string Path, out IntPtr dataPtr, out uint Count);

private void readDump(string Path)
{
    uint count = 0;
    IntPtr Data = new IntPtr();

   try{
       if(ReadFile(Path, out Data, out count) == 1) //The Program crashes just right after this statement
       {
           //Do Something ...
       }
    }
    catch() {}

}

デバッグモードとリリースモードの両方でプログラムがクラッシュします。ファイルをロードした後、デバッグモードでプログラムを一時停止し、"Visual Studio's Immediate window"でいくつかのメモリブロックを呼び出さない限り、プログラムはクラッシュします。 読み込むファイルのサイズは約64MBで、PCには2GB以上の未使用のramがあります。

UPDATEしてください。 以前は動作していたサードパーティーのプログラムが、Windows 7 (ホスト)では "Exception Code: c0000005" でクラッシュしたり、その他の奇妙なことが起こっていることに気づきました。ですから、おそらくWindows 7が関係しているのでしょう。この問題を解決するにはどうしたらよいでしょうか?

解決方法は?

もし、あなたのコードがすべて上記の通りであれば、問題はないと思います。しかし、私がこの問題に直面したとき、malloc/new/whatever がヒープ破壊を検出したことが原因であることがあります。多くの場合、この破壊はプログラムの中ですでに発生していますが、クラッシュは次の new/malloc の呼び出しまで延期されました。

もし、上記が実行されてクラッシュする前に、他のファイルを読んだり、他のバッファを確保したり解放したりした場合は、そこに問題がないか調べます。おそらく、バッファに書き込むときはどこでもアサートの束を投げて、境界と書き込んでいるものがオーバーランしていないかチェックします。 具体的な答えでなくてすみません、このアドバイスをコメントとして残せるほどの担当者ではありません。