我有一个DirectX应用程序。这很简单,但我遇到了问题。我创建设备,设备上下文等,一切正常,但是当我退出时,发生崩溃,错误是:HEAP: Free Heap block 3ad7d18 modified at 3ad7d98 after it was freed
。仅当我至少调用IDXGISwapChain Present
函数一次时才会发生这种情况。如果我不这样做,那么整个清洁过程进展顺利。此外,我在每个COM对象上调用Release
,并且只有在我释放最后一个COM对象时才会发生崩溃(顺序无关紧要)。我在Windows 7,MS Visual 2012上使用DirectX 11(Win8 SDK)。
我的消息循环功能:
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 );
我初始化并启动引擎的主要功能:
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 :(得分:3)
好的......真的很烦人。这段代码似乎很好,问题出现在司机或某事上。当我安装新驱动程序并重启PC两次时,问题就消失了。
答案 1 :(得分: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()
堆栈:)