Skip to main content
gamedev.net
🔒 Locked

delete[] direct3d vertex buffer memory?

Started by sirlemonhead 11 replies 8.1k views
Original Post
sirlemonhead
sirlemonhead
I ->Release() my Direct3D Vertex Buffer fine, but what about the memory I allocate for it? Ie I have: #define MAX_VERTEXES 4096//9216 #define MAX_INDICES 9216 D3DTLVERTEX *mainVertex = new D3DTLVERTEX[MAX_VERTEXES]; WORD *mainIndex = new WORD[MAX_INDICES]; WORD *tempIndex = new WORD[MAX_INDICES]; as a global.. in a c++ file. now, I'm guessing I should be calling delete[] mainVertex; when it's time to close the app? I'm calling the delete operator after I do a ->Release() on the Vertex Buffer that I lock with this D3DTLVERTEX array. but doing this gives me a debug error, the nasty "_BLOCK_TYPE_IS_VALID(pHead->nBblockUse)" I'm not doing anything else with the data before that, not accidentally deleting it twice. I haven't got a deconstructor for D3DTLVERTEX so the code is pretty much D3DTLVERTEX *mainVertex = new D3DTLVERTEX[MAX_VERTEXES]; lock, fill, render with etc etc time to close the application, do ReleaseVolatileResources(); // Releases Vertex and index buffer SAFE_RELEASE(d3d.lpD3DDevice); SAFE_RELEASE(d3d.lpD3D); then I try do delete[] mainVertex but I get the _BLOCK_TYPE_IS_VALID(pHead->nBblockUse) error What am I doing wrong? do I need to even release this memory? I'm assuming yes but I always get uncertain when stuff doesn't work AND I don't think ive ever seen anyone else do it..
Evil Steve
Evil Steve
You never delete D3D objects, they're allocated by D3D. When you call Release() on an object, it decrements it's reference count, and when it reaches zero, the object is automatically deleted (Internally, it calls "delete this;").

As for any memory you allocate with new/new[], you need to free that with delete/delete[].

That error usually means that you've overrun the array you allocated, and tramped over ther CRT's book keeping information in the process. Check that you're not e.g. allocating 100 vertices and writing 101, or writting one past the end of the array.
sirlemonhead
sirlemonhead
Yeah, I know not to use delete for d3d objects (only for stuff with new)

I'll have a look at my code.. I can already think of a place where I might be overrunning the array. I guess I just assumed i'd get a big error if I had gone out of bounds. I'll check it tomorrow. Thanks :)
jollyjeffers
jollyjeffers
Quote:
Original post by sirlemonhead
I guess I just assumed i'd get a big error if I had gone out of bounds.
Yeah, you'll get a big error - just it may not happen when you expect, may not look like you expect and might well cause your computer to catch fire.

Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ |
sirlemonhead
sirlemonhead
I do have bizzare rendering errors..minor, but I can't for the life of me figure it out. I'll hopefully have a chance to tinker with my code over the weekend and get back to you :)
Namethatnobodyelsetook
Namethatnobodyelsetook
You don't allocate memory for the VB. The CreateVB call allocates it, and Lock will give you a pointer to it.

What I think you're doing is locking, and passing the pointer to your own memory buffer. This just overwrites your pointer with D3D's pointer. You write data. It goes into the VB. You unlock. You release the VB, then finally, you attempt to free your memory block... but you lost that pointer a long time ago. You're deleting a pointer that makes no sense to delete, and it fails.

Option 1: Stop allocating and deleting memory at all, and just write to the VB.

Option 2: Pass some other temporary pointer to lock. Copy from your local buffer to the VB using memcpy from your buffer to that temporary pointer, then unlock. When you're done you can release the VB and delete your memory in any order you choose. They are not tied together at all.

Option 3: Tell me how I have it all wrong. ;)
sirlemonhead
sirlemonhead
Quote:
Original post by Namethatnobodyelsetook
You don't allocate memory for the VB. The CreateVB call allocates it, and Lock will give you a pointer to it.

What I think you're doing is locking, and passing the pointer to your own memory buffer. This just overwrites your pointer with D3D's pointer. You write data. It goes into the VB. You unlock. You release the VB, then finally, you attempt to free your memory block... but you lost that pointer a long time ago. You're deleting a pointer that makes no sense to delete, and it fails.

Option 1: Stop allocating and deleting memory at all, and just write to the VB.

Option 2: Pass some other temporary pointer to lock. Copy from your local buffer to the VB using memcpy from your buffer to that temporary pointer, then unlock. When you're done you can release the VB and delete your memory in any order you choose. They are not tied together at all.

Option 3: Tell me how I have it all wrong. ;)


I'm not sure I follow you at all, Could you explain what you mean?

This is basically what I do:

// 1: create the memoryD3DTLVERTEX *mainVertex = new D3DTLVERTEX[MAX_VERTEXES];// 2: Create vertex buffer		LastError = d3d.lpD3DDevice->CreateVertexBuffer(4096 * sizeof(D3DTLVERTEX),D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_TLVERTEX, D3DPOOL_DEFAULT, &d3d.lpD3DVertexBuffer, NULL);		if(FAILED(LastError)) {			LogDxError(LastError);			return FALSE;		}// 3: Lock vertex buffer	LastError = d3d.lpD3DVertexBuffer->Lock(0, 0, (void**)&mainVertex, D3DLOCK_DISCARD);	if(FAILED(LastError)) {		LogDxError(LastError);		return FALSE;	}// 4: Fill it up during a frame, eg	// bottom left	mainVertex[vb].sx = (float)topX - 0.5f;	mainVertex[vb].sy = (float)topY + height - 0.5f;	mainVertex[vb].sz = 0.0f;	mainVertex[vb].rhw = 1.0f;	mainVertex[vb].color = D3DCOLOR_ARGB(255,255,255,255);	mainVertex[vb].specular = RGBALIGHT_MAKE(0,0,0,255);	mainVertex[vb].tu = 0.0f;	mainVertex[vb].tv = (1.0f / real_height) * height;	vb++;	// top left	mainVertex[vb].sx = (float)topX - 0.5f;	mainVertex[vb].sy = (float)topY - 0.5f;	mainVertex[vb].sz = 0.0f;	mainVertex[vb].rhw = 1.0f;	mainVertex[vb].color = D3DCOLOR_ARGB(255,255,255,255);	mainVertex[vb].specular = RGBALIGHT_MAKE(0,0,0,255);	mainVertex[vb].tu = 0.0f;	mainVertex[vb].tv = 0.0f;	vb++;etc etc// 5: unlock VB	LastError = d3d.lpD3DVertexBuffer->Unlock();	if(FAILED(LastError)) {		LogDxError(LastError);		return FALSE;	}// 6: render	LastError = d3d.lpD3DDevice->SetStreamSource( 0, d3d.lpD3DVertexBuffer, 0, sizeof(D3DTLVERTEX));	if (FAILED(LastError)){		LogDxError(LastError);	}	LastError = d3d.lpD3DDevice->SetFVF(D3DFVF_TLVERTEX);	if (FAILED(LastError)){		LogDxError(LastError);	}	LastError = d3d.lpD3DDevice->SetIndices(d3d.lpD3DIndexBuffer);	if(FAILED(LastError)) {		LogDxError(LastError);	}


I have an index buffer too (should I bother with this for a dynamic vertex buffer? the scenes in this game are really tiny, 4-5k per frame perhaps at the most)

I don't know how to do the above any other way. Would you mind explaining? I'm still learning here :)
ET3D
ET3D
You don't allocate memory for the lock buffer. Direct3D returns its own memory after the lock. Just define "D3DTLVERTEX *mainVertex;", use the memory space after the lock, and it'd be released when you unlock.
sirlemonhead
sirlemonhead
Cool, so I don't need to do a delete[] at all if I do it that way?
Buckeye
Buckeye
Quote:
so I don't need to do a delete[] at all .. ?


Correct. As noted above, the device will allocate the memory and just give you a pointer to that memory for your use.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
sirlemonhead
sirlemonhead
Ok, I got by confused by him saying that the memory will be released when I unlock. Did he mean to say it'll be released (ie freed) when I do a ->Release() on my Vertex Buffer?

Cheers guy :)
Buckeye
Buckeye
Quote:
memory will be released when I unlock. Did he mean to say it'll be released (ie freed) when I do a ->Release() on my Vertex Buffer?

Release is not the same as free or delete! Don't confuse the terms.

Yes, the memory will be "disposed" of by DirectX when you're done with the VB and release it. Not when you Unlock the VB, but when you Release the VB.

EDIT: It probably does sound confusing - but the idea is that DirectX will take care of the memory for you, provided you Release anything you Create when you're done with it.

Are you sufficiently confused yet? [smile]
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
sirlemonhead
sirlemonhead
Nope, I have it now, thanks :) I'll sort you guys out with some positive rep

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.