C++ Stack Overflow

Started by
5 comments, last by Codarki 13 years, 1 month ago
I can't spot this for the life of me. I was taking code from one project and putting it in another, it's almost identical yet it fails to work on my new project.

Struct that I am passing:

struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR; FLOAT U, V;};

LPDIRECT3DVERTEXBUFFER9 particle1VertBuffer; // the pointer to the particle's vertex buffer



// create the vertices using the struct
struct CUSTOMVERTEX t_vert[] =
{
{-1.6f, 1.6f, 0.0f, D3DCOLOR_XRGB(139, 137, 137), 1, 0,},
{-1.6f, -1.6f, 0.0f, D3DCOLOR_XRGB(139, 137, 137), 0, 0,},
{1.6f, 1.6f, 0.0f, D3DCOLOR_XRGB(139, 137, 137), 1, 1,},
{1.6f, -1.6f, 0.0f, D3DCOLOR_XRGB(139, 137, 137), 0, 1,},
};

// create a vertex buffer interface called particle1VertBuffer
d3ddev->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&particle1VertBuffer,
NULL);
VOID* pVoid;

// lock particle1VertBuffer and load the vertices into it
particle1VertBuffer->Lock(0, 0, (void**)&pVoid, 0);

memcpy(pVoid, t_vert, sizeof(t_vert));

particle1VertBuffer->Unlock();



Car->passVertBuffer(particle1VertBuffer);


The stack and heap size are the default sizes (1MB ). I changed both to 2MB and the overflow is still occurring.
Advertisement
I had a similar problem, recently.

I found my app would work fine as a console app by adjusting the stack size. But, I found adjusting the stack size within a Windows app made no difference at all and I was back to my stack overflow problem.

In the end I have used Malloc and everything is working 100%.

Hope this helps. ;)
When it overflows, have you inspected the call stack in the debugger? Is the call stack really deep for some reason?
[color="#1C2837"][color="#000000"] VOID[color="#666600"]*[color="#000000"] pVoid[color="#666600"]; [color="#880000"]// lock particle1VertBuffer and load the vertices into it[color="#000000"]
particle1VertBuffer[color="#666600"]->[color="#660066"]Lock[color="#666600"]([color="#006666"]0[color="#666600"], [color="#006666"]0[color="#666600"], [color="#666600"]([color="#000088"]void[color="#666600"]**)&[color="#000000"]pVoid[color="#666600"], [color="#006666"]0[color="#666600"]);[color="#000000"]

memcpy[color="#666600"]([color="#000000"]pVoid[color="#666600"],[color="#000000"] t_vert[color="#666600"], [color="#000088"]sizeof[color="#666600"]([color="#000000"]t_vert[color="#666600"]));
[color="#666600"]

[color="#666600"]

[color="#666600"]

[color="#666600"]

[color="#666600"]^
Looks a bit sus ... have you checked return codes to all of your D3D functions?
I would have coded that last bit as something like this instead: CUSTOMVERTEX *pVoid = NULL;
particle1VertBuffer->Lock (0, 0, (void **) &pVoid, 0);
memcpy (pVoid, t_vert, sizeof (CUSTOMVERTEX) * 4);
particle1VertBuffer->Unlock ();

I'm not seeing why this would cause a stack overflow though, unless you're declaring t_vert as a local and you're really really tight on stack space at the time you create the vertex buffer. Run it in a debugger and it will break on the line where the overflow occurs.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


I would have coded that last bit as something like this instead: CUSTOMVERTEX *pVoid = NULL;
particle1VertBuffer->Lock (0, 0, (void **) &pVoid, 0);
memcpy (pVoid, t_vert, sizeof (CUSTOMVERTEX) * 4);
particle1VertBuffer->Unlock ();

I'm not seeing why this would cause a stack overflow though, unless you're declaring t_vert as a local and you're really really tight on stack space at the time you create the vertex buffer. Run it in a debugger and it will break on the line where the overflow occurs.


The difference is that he didn't initialize pVoid to null, so if particle1VertBuffer->Lock() fails, pVoid would contain garbage. Incidentally, this garbage would then serve as the destination address to which memcpy() writes its stuff, which could very well ruin the stack (and other things).

Always initialize all variables, never just declare them without giving them a sane initial value. And always assume that functions that can fail WILL fail (so check the damned return value!). Also, a few assert()'s here and there wouldn't hurt.
If you only added that code, then you made changed to the caller code aswell. Might be bugged there too. Does this happen in Release and Debug builds? What does the call stack looks like, just few lines if there is a repeating pattern?

You can make very easy inline function to check the return codes from D3D, and throw exception if all goes wonky (you can set VS to break at throw). Some have done it with a macro.


inline check_d3d9(HRESULT result, char* function_name)
{
// d3d9_error just gets the text with dx error lib.
if (result != S_OK)
throw d3d9_error(result, function_name);
}

// Then it is a bit easier to check functions, compared manual labor.
check_d3d9(particle1VertBuffer->Lock(0, 0, &pVoid, 0), "Direct3DVertexBuffer9::Lock");

This topic is closed to new replies.

Advertisement