我一直在遇到一個我一直在努力的遊戲,一旦我添加了音樂,它開始播放之後5-30秒內開始在我常用的紋理加載代碼中進行segfaulting 。我能想到的最好的是它是某種內存損壞。在嘗試調試它失敗(嘗試像GFlags pageheap之類的)之後,我花了一週的時間將它切成了下面的代碼,但仍然存在這個問題。Mix_PlayMusic導致內存損壞
有時,這段錯誤會導致調用堆棧經歷SDL2_mixer.dll
,但大多數情況下會發生在SDL_CreateTextureFromSurface
調用中,因爲渲染器處於不良狀態。我的機器上的numTextures達到15000-40000之間(Windows 10 x64,程序爲x86編譯)。
我的直覺告訴我,在我的環境或代碼中存在一個問題,而不是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()'文檔](https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57)沒有說優雅地處理NULL'音樂'參數。同上你的'IMG_Load()'調用。 – genpfault
@genpfault好想法。在銷燬之前和創建後以及Mix_LoadMUS中,我已經爲pTexture添加了空檢查。我也在Mix_PlayMusic中聲稱爲零。這些斷言都沒有失敗。值得注意的是,在撞車之前,音樂按預期播放。 –
非常好,謝謝你們仔細檢查並更新MCVE!接下來:您是否使用您選擇的編譯器(我正在猜測最近複製的Visual Studio?)構建SDL2,SDL_mixer和SDL_image,還是使用libsdl.org的二進制文件?如果您使用的是二進制文件,請嘗試在Debug或RelWithDebInfo模式下在本地構建它們,這將使您的回溯更加容易理解。另一個要嘗試的是在'while'循環中添加一個'SDL_PumpEvents()'。對不起,我沒有什麼更好的,你有什麼對我來說好像:( – genpfault