2017-06-03 147 views
2

我一直在遇到一個我一直在努力的遊戲,一旦我添加了音樂,它開始播放之後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); 
    } 
} 
+2

您是否確認'Mix_LoadMUS()'正在返回一個非NULL'Mix_Music *'? ['Mix_PlayMusic()'文檔](https://www.libsdl.org/projects/SDL_mixer/docs/SDL_mixer.html#SEC57)沒有說優雅地處理NULL'音樂'參數。同上你的'IMG_Load()'調用。 – genpfault

+0

@genpfault好想法。在銷燬之前和創建後以及Mix_LoadMUS中,我已經爲pTexture添加了空檢查。我也在Mix_PlayMusic中聲稱爲零。這些斷言都沒有失敗。值得注意的是,在撞車之前,音樂按預期播放。 –

+1

非常好,謝謝你們仔細檢查並更新MCVE!接下來:您是否使用您選擇的編譯器(我正在猜測最近複製的Visual Studio?)構建SDL2,SDL_mixer和SDL_image,還是使用libsdl.org的二進制文件?如果您使用的是二進制文件,請嘗試在Debug或RelWithDebInfo模式下在本地構建它們,這將使您的回溯更加容易理解。另一個要嘗試的是在'while'循環中添加一個'SDL_PumpEvents()'。對不起,我沒有什麼更好的,你有什麼對我來說好像:( – genpfault

回答

1

解決方案竟然是要更新到最新版本的SDL(2.0.3 - > 2.0.5)。

我開始開發有問題的項目,其中引擎代碼庫大約在兩年前從SDL 1.2升級到2.0,最新版本爲2.0.3。

當我最近添加聲音和音樂時,我採取了最新的SDL_mixer,並沒有想到將SDL更新到最新的2.0.5。

在獲得SDL的最新開發和運行時庫之後(問題良好,並且爲SDL_imageSDL_mixer),問題消失。

我對此並不完全滿意。我很驚訝新版本的SDL_mixer與舊的SDL成功鏈接,如果它們不兼容的話。另外,我無法在網上找到任何提示任何兼容性問題的資源。因此,我有一種不安的感覺,可能還有其他事情正在發生,這是通過升級偶然解決的。