# Specific question regarding pointer arrays. [Solved]

## Recommended Posts

Alerion    301
Ehhh, this is pretty newbie so forgive me. I realize pointers are pretty basic stuff, I just want to make sure about this. I'm using DirectX and MSVC++ Express. DirectX doesn't matter so much. Basically what I'm doing is making a function that returns an array of vertex points for a particular mesh. The function should take a pointer to a DWORD so it can return the number of verticies returned. Like this:
D3DXVECTOR3 *verts;
DWORD numVerts;
verts = testObj->getVerticies( pd3dDevice, &numVerts );

Now in the function, what I do is allocate memory for verts, the size of which is dependent on the number of vertices, like so:
*outNumVerts = getMesh()->GetNumVertices();
D3DXVECTOR3 *outVerts = new D3DXVECTOR3[ *outNumVerts ];

Ok, so here's my question. After I run the function, and use the data as I like, won't I need to delete[] verts?
D3DXVECTOR3 *verts;
DWORD numVerts;
verts = testObj->getVerticies( pd3dDevice, &numVerts );

//do stuff with Verts and NumVerts works here...

delete[] verts; //but this causes a run time error

Using :
delete verts;

Also causes errors. So, I probably deserve a few of the snickers and jeers, but what I don't understand is if I allocate memory with the new command shouldn't I free it with delete? Perhaps I am going about this all wrong? Thanks in advance! [Edited by - Alerion on August 6, 2007 3:12:32 PM]

##### Share on other sites
jyk    2094
Quote:
 Original post by AlerionOk, so here's my question. After I run the function, and use the data as I like, won't I need to delete[] verts?
Yup.

I don't know what's causing the error, but I didn't see a 'return outVerts;' anywhere. (I realize you may just not have included that line in your post...)

Could you post more of your code? (Use [ source ] tags to preserve the formatting...) Also, once you get this working, there are some technical and stylistics changes you could make that would reduce the probability of these sorts of errors popping up in the future (if you repost your code - once it's fixed that is - I'm sure you'll get some good input on improvements you could make).

##### Share on other sites
Alerion    301
Sorry, I didn't want to over complicate things, as I thought the answer would be apparent to a more experienced eye

Here's the function:
D3DXVECTOR3* getVerticies( IDirect3DDevice9* inDevice, DWORD *outNumVerts )	{		ID3DXMesh *simpleMesh;		if(FAILED( getMesh()->CloneMeshFVF( 0, D3DFVF_XYZ, inDevice, &simpleMesh )))		{			outNumVerts = NULL;			return NULL;		}		*outNumVerts = getMesh()->GetNumVertices();		D3DXVECTOR3 *outVerts = new D3DXVECTOR3[ *outNumVerts ];						simpleMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&outVerts);		simpleMesh->UnlockVertexBuffer( );		return outVerts;			}

Here's calling the function
	D3DXVECTOR3 *verts;	DWORD numVerts;	verts = testObj->getVerticies( pd3dDevice, &numVerts );        if(verts)        {	  DEBUGMSG( "Mesh Verticies: ", DB_OBJECT );	  for(DWORD i=0; i<numVerts; i++)	  {		  DEBUGMSG( IntToStr<float>(verts[i].x) + "," +			  IntToStr<float>(verts[i].y) + "," +			  IntToStr<float>(verts[i].z) + "\n", DB_OBJECT);  	  }        //This outputs fine, and the vertices are correct.	//delete verts;        //delete[] verts; //both fail        }

I would very much appreciate any stylistic suggestions.

[Edited by - Alerion on August 6, 2007 1:53:03 AM]

##### Share on other sites
Zahlman    1682
Notice how you pass a void** as the second argument to LockVertexBuffer()? That's because D3D is going to change 'outVerts' to point at memory that *it* is managing. That means you lose the pointer to your allocation, and then try to clean up D3D's allocation (which didn't necessarily get allocated with anything in particular, and is not your business anyway). Also, the names LockVertexBuffer and UnlockVertexBuffer strongly suggest (although I don't have experience with D3D :) ) that you're supposed to do the meaningful work *between* those two calls.

What you probably want to do is make a class that represents the vertex buffer, making the lock call in a constructor and the unlock call in the destructor. Probably something like:

class VertexBuffer {	D3DXVECTOR3* begin_, end_;	LPD3DXMesh source;	VertexBuffer(const VertexBuffer&); // should not be copied	VertexBuffer& operator=(const VertexBuffer&); // or assigned	// so don't implement those two!	public:	VertexBuffer(LPD3DXMesh source_original) : source(0), begin(0), end(0) {		if (FAILED(source_original->CloneMeshFVF(0, D3DFVF_XYZ, inDevice, &source))) { return; }		int count = source->GetNumVertices();		void** ptr = reinterpret_cast<void**>(&begin_);		source->LockVertexBuffer(D3DLOCK_READONLY, ptr);		end_ = begin_ + count;	}	~VertexBuffer() { 		if (source) { source->UnlockVertexBuffer(); }	}	D3DXVECTOR3* begin() { return begin_; }	D3DXVECTOR3* end() { return end_; }};VertexBuffer verts(pd3dDevice);DEBUGMSG("Mesh Vertices: ", DB_OBJECT);for (D3DXVECTOR3* ptr = verts.begin(); ptr != verts.end(); ++ptr) {	DEBUGMSG(IntToStr<float>(ptr->x) + "," +	         IntToStr<float>(ptr->y) + "," +	         IntToStr<float>(ptr->z) + "\n", DB_OBJECT);}// No extra cleanup, no if-check.

##### Share on other sites
JohnBolton    1372
You are using LockVertexBuffer incorrectly. When LockVertexBuffer is called, it returns a pointer to the vertex buffer via the second parameter. In your case, the returned value is overwriting the value in the pointer outVerts.

There is no reason to do the new, and thus no reason to do the delete.

##### Share on other sites
Alerion    301
Brilliant, much obliged =]