1

ランダム化されたピッチをサウンド サンプルに追加する作業を行っていましたが、現在は正常に機能していますが、使用が終わった後にチャンクを解放しようとすると Mix_FreeChunk() がクラッシュします。

問題を再現する簡単なテストを作成しました (SDL 1.2.14 および SDL_mixer 1.2.11):

Mix_Chunk* s1 = rexResourceMgr->getSoundFromFile("data/audio/UI/ALARM.ogg"); // uses Mix_LoadWAV_RW/SDL_RWops to load sample

Mix_Chunk* s2 = (Mix_Chunk*)malloc(sizeof(Mix_Chunk));
s2->allocated = 1;
s2->alen = s1->alen;
s2->abuf = (Uint8*)malloc(s2->alen * sizeof(Uint8));
memcpy(s2->abuf,s1->abuf,s2->alen);
s2->volume = s1->volume;

Mix_FreeChunk(s1); // <-- works fine
Mix_FreeChunk(s2); // <-- crashes somewhere in SDL/SDL_Mixer

s1 は Mix_LoadWAV_RW を使用してファイルからロードされ、s2 はメモリ内に作成された s1 の正確なコピーです。後者は解放時にクラッシュしますが、前者はクラッシュしません。なぜこれが起こっているのか、誰にも手がかりがありますか? 私はこれに何時間も費やし、SDL_Mixer で起こっていることに絞り込みましたが、クラッシュしたときに基になるソースで何が起こっているかを確認する方法がありません。今ではテストは非常に単純で、正確なコピーです。元のサンプルですが、それでも失敗します...

特定のエラー メッセージの例: 「game.exe の 0x77c5e3be での初回例外: 0xC0000005: アクセス違反の読み取り場所 0x69b0f1d8.」

メモリを解放できないのはなぜですか?

編集: 分離されたテストをさらに調べた後、HeapFree(_crtheap, 0, pBlock) 呼び出し中に s2 の解放が free.c で具体的にクラッシュしているため、これらの数行のスペースでヒープが破損していますか? Mix_FreeChunk() の中間コードは実際には非常に単純で、多かれ少なかれバッファで free() を呼び出すだけです。では、なぜ s1 は問題ないのに s2 が失敗するのでしょうか?

4

1 に答える 1

1

問題は、Windows の複数のヒープにあるようです。

デバッガーでサンプル コードを分析したところ、SDL_mixer 関数は msvcrt.dll からMix_FreeChunk()使用さfree()れ、呼び出しコードmalloc()は最新の Visual C ランタイム ライブラリ (msvcr110.dll や静的バージョンなど) の 1 つから呼び出されました。

これを呼び出しても違いはありません。SDL_malloc()実際には#define SDL_malloc malloc.

malloc()私が見る1つの解決策は、msvcrt.dllからも強制的に使用することです:

#include <windows.h>

...

typedef void* (*malloc_t)(size_t);
malloc_t msvcrt_malloc = reinterpret_cast<malloc_t>(
    GetProcAddress(GetModuleHandle(TEXT("msvcrt")), "malloc"));

...

Mix_Chunk* s2 = (Mix_Chunk*)msvcrt_malloc(sizeof(Mix_Chunk));
s2->abuf = (Uint8*)msvcrt_malloc(s2->alen * sizeof(Uint8));

その後、プログラムはクラッシュしなくなりました。

より良いオプションは、最終的なアプリケーションとまったく同じ環境設定で、SDL_mixer および/または SDL ライブラリを自分でコンパイルすることです。

于 2014-04-24T01:45:01.797 に答える