私が取り組んでいたゲームに問題がありました。プレイした後、5〜30秒後に頻繁に呼び出されるテクスチャ読み込みコードでsegfaultingを開始した曲を追加しました。私が思いつくことができる最高ののは、ある種の記憶腐敗であるということでした。 (GFlags pageheapのようなものを試して)それをデバッグしようとしてうまくいっていない週の良い週の後、私は問題を示している次のコードにカットダウンすることができました。Mix_PlayMusicがメモリ破損の原因となった
ときどき呼び出しスタックがSDL2_mixer.dll
を通過することがありますが、レンダラーの状態が悪いため、ほとんどはSDL_CreateTextureFromSurface
呼び出しで発生します。 numTexturesは私のマシン(Windows 10 x64、x86用にコンパイルされたプログラム付き)で15000〜40000になる。
自分の環境やコードには、SDL自体の問題ではなく、問題があることがわかりますが、私は迷っています。助けや洞察力があれば大いに感謝します。
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <cassert>
int main(int argc, char* argv[])
{
assert(SDL_Init(SDL_INIT_EVERYTHING) == 0);
SDL_Window * pWindow_ = SDL_CreateWindow(
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0x0);
assert(pWindow_ != nullptr);
SDL_Renderer * pRenderer_ = SDL_CreateRenderer(pWindow_, -1, 0);
assert(pRenderer_ != nullptr);
assert(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 512) == 0);
Mix_Music * pMusic = Mix_LoadMUS("sounds/tranquility.wav");
assert(pMusic != nullptr);
assert(Mix_PlayMusic(pMusic, -1) == 0);
SDL_Surface * pSurface = IMG_Load("images/caution.png");
assert(pSurface != nullptr);
SDL_Texture * pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface);
assert(pTexture != nullptr);
int numTextures = 0;
while (true)
{
numTextures += 10;
assert(pTexture != nullptr);
SDL_DestroyTexture(pTexture);
pTexture = SDL_CreateTextureFromSurface(pRenderer_, pSurface);
assert(pTexture != nullptr);
}
}
'Mix_LoadMUS()'がNULLでない 'Mix_Music * 'を返すことを確認しましたか? ['Mix_PlayMusic()' docs](https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57)は、NULLの '音楽'引数をうまく扱うことについて何も言いません。あなたの 'IMG_Load()'呼び出しのために。 – genpfault
@genpfault良い考え。破壊する前と作成した後、そしてMix_LoadMUSでpTextureのヌルチェックを追加しました。私はMix_PlayMusicでもゼロを主張しています。それらの主張は失敗しません。そしてクラッシュするまで、音楽は期待通りに演奏されることは注目に値する。 –
優秀、MCVEの更新を確認していただきありがとうございます!次のページ:あなたの選択したコンパイラでSDL2、SDL_mixer、およびSDL_imageをビルドしましたか(最近のヴィジュアルスタジオを推測していますか?)、またはlibsdl.orgのバイナリを使用していますか?バイナリを使用している場合は、デバッグまたはRelWithDebInfoモードでローカルにビルドしてみてください。そうすれば、バックトレースがより分かりやすくなります。もう一つは 'while'ループに' SDL_PumpEvents() 'を追加することです。申し訳ありませんが、私はあなたに見えている何かを良くしていない申し訳ありません: – genpfault