• Advertisement
Sign in to follow this  

Odd stack write violation in struct (C++)

This topic is 2014 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys I hope you can help me out here.
So I've got a header file which looks like this:

[CODE]
/*
****************************************************
GraphicsDescription.h - Header File
Usage: Describes information for rendering
****************************************************
*/

#pragma once
// Library includes
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
#pragma comment(lib, "DXErr.lib")

// Includes
#include <D3D11.h>
#include <D3DX11.h>
#include <D3DX10.h>
#include <DxErr.h>
#include <xnamath.h>

enum Fill_Mode
{
Solid,
Wireframe,
};

struct GraphicsDescription
{
D3D11_VIEWPORT viewport;
bool VSync;
Fill_Mode fillMode;
};
[/CODE]

Now when I run this what I get is the following error:

"An unhandled exception of type 'System.AccessViolationException' occured in Unknown Module."

Now while I was trying around I noticed this odd behavior.

If I replace the enum (or rather the third variable) with anything lower than 2 bytes it works. But anything higher than that .e.g int -> same error.
I've tried placing something like "char padding[256]" in there put that didn't help either.

Anyone knows whats going on here ? Edited by lipsryme

Share this post


Link to post
Share on other sites
Advertisement
The code compiles and runs fine. (The header file doesn't tell us anything useful if you don't show how you're using it.) Where does it crash?

Share this post


Link to post
Share on other sites
Hmm it seems to crash somewhere inside an xnamathmatrix.inl file in this part here I think:
[CODE]
XMFINLINE _XMMATRIX& _XMMATRIX::operator=
(
CONST _XMMATRIX& M
)
{
r[0] = M.r[0];
r[1] = M.r[1];
r[2] = M.r[2];
r[3] = M.r[3];
return *this;
}
[/CODE]


Well if I comment the function that calls this out I still get the same error just a little bit later at another xnamath based function it seems.

Which would be this line:
[CODE]
this->camPosition = XMVectorSet(camDesc.cameraPosition.x, camDesc.cameraPosition.y, camDesc.cameraPosition.z, 0.0f);
[/CODE] Edited by lipsryme

Share this post


Link to post
Share on other sites
Well I'm not sure where to start. I'm going to give you the code parts that happen between this declaration and the error I guess.

[CODE]
// Define information of our engine
EngineDescription engineDesc;
// Graphics
engineDesc.graphicsDesc.VSync = true;
engineDesc.graphicsDesc.viewport.TopLeftX = 0.0f;
engineDesc.graphicsDesc.viewport.TopLeftY = 0.0f;
engineDesc.graphicsDesc.viewport.MinDepth = 0.0f;
engineDesc.graphicsDesc.viewport.MaxDepth = 1.0f;
engineDesc.graphicsDesc.viewport.Width = (float)engineDesc.windowDesc.windowWidth;
engineDesc.graphicsDesc.viewport.Height = (float)engineDesc.windowDesc.windowHeight;

// Initialize our engine
Engine* engine = new Engine(engineDesc);

[/CODE]

Now its being passed to the engine constructor:

[CODE]
Engine::Engine(EngineDescription &engineDesc)
{
// Save data
this->engineDesc = engineDesc;
this->isRunning = false;
// Initialize member
this->renderer = NULL;
this->window = NULL;
this->camera = NULL;

// Initialize Engine
this->Initialize();
}
[/CODE]

Next up is the Initialize function:

[CODE]
void Engine::Initialize()
{
// Creates our window
this->window = new Window(this->engineDesc.windowDesc);
// Check if it worked ?
if(!this->window->IsInitialized())
{
// It failed -> abort engine
this->isRunning = false;
MessageBoxW(NULL, L"Failed to initialize Window", L"Engine::Initialize()", MB_OK | MB_ICONERROR);
return;
}

// Creates our renderer
this->renderer = new Renderer(this->engineDesc.graphicsDesc, this);
// Check if it worked ?
if(!this->renderer->IsInitialized())
{
// It failed -> abort engine
this->isRunning = false;
MessageBoxW(NULL, L"Failed to initialize Renderer", L"Engine::Initialize()", MB_OK | MB_ICONERROR);
return;
}
[/CODE]

This will pass the graphicsDesc to the renderer's constructor:

[CODE]
Renderer::Renderer(GraphicsDescription graphicsDesc, Engine* engine)
{
// Save data
this->graphicsDesc = graphicsDesc;
this->engine = engine;

// Initialize member
this->isInitialized = false;
this->device = NULL;
this->deviceContext = NULL;
this->swapChain = NULL;
this->renderTargetView = NULL;

// Initialize Renderer
this->InitializeRenderer();
}
[/CODE]

Then do InitializeRenderer()
[CODE]
void Renderer::InitializeRenderer()
{
HRESULT hr;
// Describe our Buffer
DXGI_MODE_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
bufferDesc.Width = this->engine->GetScreenWidth();
bufferDesc.Height = this->engine->GetScreenHeight();
bufferDesc.RefreshRate.Numerator = (this->graphicsDesc.VSync) ? 60 : 0;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// Describe our SwapChain
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = this->engine->GetWindow()->GetHwnd();
swapChainDesc.Windowed = this->engine->IsWindowed();
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
// Create our Swap Chain
hr = D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL, NULL, NULL, NULL,
D3D11_SDK_VERSION,
&swapChainDesc,
&this->swapChain,
&this->device,
NULL,
&this->deviceContext);
if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}

// Create our BackBuffer
ID3D11Texture2D* BackBuffer;
hr = this->swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}

// Create our Render Target
hr = this->device->CreateRenderTargetView(BackBuffer, NULL, &this->renderTargetView);
BackBuffer->Release();
if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}

// Describe our DepthStencilBuffer
D3D11_TEXTURE2D_DESC depthStencilDesc;
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));
depthStencilDesc.Width = this->engine->GetScreenWidth();
depthStencilDesc.Height = this->engine->GetScreenHeight();
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
// Create the DepthStencil View
hr = this->device->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}

hr = this->device->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);
if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}
// Set our RenderTarget
this->deviceContext->OMSetRenderTargets(1, &this->renderTargetView, this->depthStencilView);

// Set the Viewport
this->deviceContext->RSSetViewports(1, &this->graphicsDesc.viewport);

// Create the constant buffer
D3D11_BUFFER_DESC cbBufferDesc;
ZeroMemory(&cbPerObjectBuffer, sizeof(D3D11_BUFFER_DESC));
cbBufferDesc.Usage = D3D11_USAGE_DEFAULT;
cbBufferDesc.ByteWidth = sizeof(cbPerObject);
cbBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbBufferDesc.CPUAccessFlags = 0;
cbBufferDesc.MiscFlags = 0;
hr = this->device->CreateBuffer(&cbBufferDesc, NULL, &this->cbPerObjectBuffer);

if(FAILED(hr))
{
MessageBoxW(NULL,
DXGetErrorDescriptionW(hr),
TEXT("D3D11CreateDeviceAndSwapChain"),
MB_OK | MB_ICONERROR);
this->isInitialized = false;
return;
}
// Initialize World Matrix with identity matrix
// this->World = XMMatrixIdentity();
//THIS IS THE LINE WHERE IT CRASHES SOMEWHERE INSIDE ITS XNAMATH file


}
[/CODE]

Share this post


Link to post
Share on other sites
If I comment that line out it crashes at that function I wrote earlier where I set the cameraPosition.

But how is it that I get this odd behavior. I mean if I leave the struct at 2 variables it works perfectly. Edited by lipsryme

Share this post


Link to post
Share on other sites
Just taking a shot in the dark:
The following lines look odd to me:
[source lang="cpp"]D3D11_BUFFER_DESC cbBufferDesc;
ZeroMemory(&cbPerObjectBuffer, sizeof(D3D11_BUFFER_DESC));[/source]
I think you might have mixed your arguments. Edited by scniton

Share this post


Link to post
Share on other sites
[quote name='scniton' timestamp='1342213417' post='4958913']
Just taking a shot in the dark:
The following lines look odd to me:
[code]D3D11_BUFFER_DESC cbBufferDesc;
ZeroMemory(&cbPerObjectBuffer, sizeof(D3D11_BUFFER_DESC));[/code]
I think you might have mixed your arguments.
[/quote]

Yes, it is quite possible that [tt]cbPerObjectBuffer[/tt] is smaller in size than [tt]D3D11_BUFFER_DESC[/tt], causing ZeroMemory to trample over nearby memory. Whether or not this is the main problem remains unknown.

Since this is C++, there is a less error-prone way to zero-initialize structs:
[code]
D3D11_BUFFER_DESC cbBufferDesc = {}; // Zero-initialized
// ZeroMemory( &cbBufferDesc, sizeof(cbBufferDesc) ); // Same effect
[/code]

Share this post


Link to post
Share on other sites
Can you post your complete code, e.g. in a zip file? Unfortunately it's really hard to diagnose something like this (since there are probably multiple contributing problems) by just seeing random snippets.

Share this post


Link to post
Share on other sites
[b]Update[/b]: I believe I might have found the problem. According to this page [url="http://www.asawicki.info/news_1429_xna_math_and_access_violation.html"]http://www.asawicki...._violation.html[/url]
it has something to do with memory alignment and SSE and that you cannot use XMVECTOR or XMMATRIX inside a dynamically allocated structure (like my class).
I'm currently trying to work my way around it using XMFLOAT3 and XMFLOAT4X4 to store them and I think it works. Still need some time to check.

[b]Update2[/b]: It works! It really was the problem. Edited by lipsryme

Share this post


Link to post
Share on other sites
For reference, that's what I was referring to here:

[quote name='ApochPiQ' timestamp='1342208388' post='4958887']
I suspect the World matrix isn't aligned correctly.
[/quote]

Although in all fairness it's a big leap from that terse quote to the fix you've got.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement