2013-05-28 80 views
3

我有一個DirectX應用程序。這很簡單,但我有一個問題。我創建設備,設備上下文等,一切正常,但當我退出時,發生崩潰,錯誤是:HEAP: Free Heap block 3ad7d18 modified at 3ad7d98 after it was freed。只有當我至少調用一次IDXGISwapChain Present函數時纔會發生。如果我不這樣做,那麼整個清潔過程就會順利進行。此外,我在每個COM對象上調用Release,並且只有當釋放最後一個COM對象時纔會發生崩潰(順序無關緊要)。我使用DirectX 11(Win8的SDK)在Windows 7中,微軟的Visual 2012清潔DirectX應用程序時崩潰

我的消息循環功能:

int Engine::run(){ 

    MSG msg = { 0 }; 
    mTimeCounter->restart(); // doesn't matter 
    while(msg.message != WM_QUIT){ 
     if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){ 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } else { 
      updateScene(mTimeCounter->deltaTime()); 
      drawScene(); 
     } 
    } 

    return static_cast<int>(msg.wParam); 
} 

updateScene什麼也不做,現在,繪製現場只稱這兩個功能:

void Engine::sceneBegin(){ 
    static FLOAT color[] = { 0.05f, 0.15f, 0.05f, 1.0f }; 
    mDeviceContext->ClearRenderTargetView(mBackBufferView, color); 
    mDeviceContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); 
} 


void Engine::sceneEnd(){ 
    mSwapChain->Present(0, 0); // crash do not occure if i comment this line of code 
} 
消息

部分切換:

case WM_QUIT : // i do not receive it even once because i press window's X button and it destroy window before i could receive WM_QUIT (or not? :P) 
    { 

       DestroyWindow(mMainWnd); 
      } 
      break; 

      case WM_DESTROY : // i receive it if press window's X button 
      { 
       PostQuitMessage(0); 
      } 
      break; 
return DefWindowProc(hWnd, msg, wParam, lParam); 

中,我初始化和啓動我的演義主要功能NE:

EngTest *eng = new EngTest(); 
eng->initialize(hInstance, L"Hi", show); 
int r = eng->run(); 
delete eng; // crash occures here but only if i call Present at least once. 

關機:

// called in Engine's destructor 
void Engine::shutdown(){ 
    RELEASE_COM(mDepthStencilView); 
    RELEASE_COM(mDepthStencilBuffer); 
    RELEASE_COM(mBackBufferView); 
    RELEASE_COM(mSwapChain); 
    if(mDeviceContext) 
     mDeviceContext->ClearState(); 
    RELEASE_COM(mDeviceContext); 
    RELEASE_COM(mDevice); 
} 

RELEASE_COM

#define RELEASE_COM(x) { if(x != NULL) { x->Release(); x = NULL; } } 
+0

一個快速評論你的窗口過程代碼:WM_QUIT將永遠不會讓它到窗口過程,因爲它意味着消息泵(你的PeekMessage調用)的信號,該程序的窗口已經全部關閉了,該計劃也應該關閉。在調用PeekMessage之後,但在調用Translate/DispatchMessage之前,您應該檢查WM_QUIT。您可能需要WM_CLOSE,當用戶請求關閉窗口時(即點擊X按鈕或按下Alt + F4或從窗口菜單中選擇關閉),該WM_CLOSE將被觸發。 另外你的代碼風格讓我想起弗蘭克盧娜的... – Alex

+0

我認爲你是正確的WM_QUIT消息,謝謝:)現在它是相當老的代碼。我開始使用智能指針和智能指針。我有一本弗蘭克盧娜的書。這對於DirectX 11而且我喜歡它:) –

回答

3

好...這實在是煩人。這段代碼似乎很好,問題在於驅動程序或某事。當我安裝新的驅動程序並重新啓動PC兩次然後問題消失。

+0

你正在使用哪個驅動程序? – Abhinav

+0

我不確定。首先,我有GeForce 540M。現在,我使用NVIDIA GeForce Experience軟件的驅動程序v。320.18,這是我之前沒有更新的軟件。我只能估計自我上次更新驅動程序以來的時間。也許這是3個月,但我不確定,對不起 –

0

對於什麼是值得的,這是我如何解決完全相同的問題。發生只有Clear()在渲染代碼,只有當D3D11_CREATE_DEVICE_DEBUG是在(添加到神祕)

case WM_CLOSE: // X clicked or Alt+F4 
    ::DestroyWindow(hWnd); // triggers WM_DESTROY 
    break; 
case WM_DESTROY: 
    gD3d11Context->ClearState(); 
    PostQuitMessage(0); // this triggers the WM_QUIT to break the loop 
    break; 

另外,我有包裝在一個自定義ComPtr實現我的指針。他們是班級的成員,並以相反的順序自毀。所以沒有->Release()堆棧:)