Trouble with Dynamic Array

I'm building a flat-terrain generator for DX, and I need to make the size of the terrain according to passed-parameters. I have a working algorithm, which uses two arrays, vertex and indice. Because arrays need to be set at compile time, I can't set them at runtime according to passed parameters.
I tried the obvious, which is to use a dynamic array:
 
  CUSTOMVERTEX *vertices = new CUSTOMVERTEX[numVerts];

which replaces the "set-at-compile-time":
 
  CUSTOMVERTEX vertices[25];

The compiler has no problem with the dynamic-approach, but the result (as opposed to the compile-time version) is nothing visible.
Here's my entire "vertex/indice loading" code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	
	CUSTOMVERTEX vertices[25];<<<<THIS IS WHAT I AM ATTEMPTING TO REPLACE WITH
        CUSTOMVERTEX *vertices = new CUSTOMVERTEX[25];        

	D3DXVECTOR3 pos = D3DXVECTOR3(minBounds.x, 0.0f, minBounds.z);
	int count = 0;
	for (int z = 0; z < numVertsZ; z++)
	{
		pos.x = minBounds.x;
		for (int x = 0; x < numVertsX; x++)
		{
			vertices[count].pos = pos;
			pos.x += stepX;
			count++;
		}
		pos.z += stepZ;
	}

	short indices[96];
	count = 0;
	int vIndex = 0;
	for (int z = 0; z < numCellsHigh; z++)
	{
		for (int x = 0; x < numCellsWide; x++)
		{
			indices[count++] = vIndex;
			indices[count++] = vIndex + numVertsX;
			indices[count++] = vIndex + numVertsX + 1;
			indices[count++] = vIndex;
			indices[count++] = vIndex + numVertsX + 1;
			indices[count++] = vIndex + 1;
			vIndex++;
		}
		vIndex++;
	}		
	
	d3ddev->CreateVertexBuffer(25 * sizeof(CUSTOMVERTEX),0,CUSTOMFVF,D3DPOOL_MANAGED,&v_buffer,NULL);
	VOID* pVoid;
	v_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, vertices, sizeof(vertices)); <<<COULD THE PROBLEM BE HERE???
	v_buffer->Unlock();	
	
	d3ddev->CreateIndexBuffer(96 * sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &i_buffer, NULL);
	i_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, indices, sizeof(indices));
	i_buffer->Unlock();

The entire routine is set in a class that is responsible for rendering, and it works just fine, as long as I use compile-time constants in the vertex and index array sizes, which defeats my purpose; the sizes need to be set during runtime.
My question is, am I applying the use of "new" incorrectly there? As I stated, if I just use the fixed-at-compile "CUSTOMVERTEX vertices[25]" there is no problem. I'm not sure if the array is not filling, or the way the vertexbuffer "memcpy" call is addressing the "new" array.
Any help would be cool. Cheers!
Last edited on
New-expressions return pointers, not arrays.
This is because arrays carry their size as part of their type, which is not possible when the size is known only at runtime.

Note that the result of the sizeof expression on line 40 depends on the type of vertices.

You want the number of elements, which is what you get when vertices is an expression with array type, but when vertices is just a pointer you just get the size of the pointer. Replace that with the number of elements in the dynamic collection.

Also, consider using std::vector, or if that is not suitable due to interoperatbility concerns, std::unique_ptr<CUSTOMVERTEX[]>.

Last edited on
The problem is a combination of two facts:
1) sizeof calculates the size of given object in compile time
2) pointer is different to array

So, in your program, instead of using sizeof() to calculate the buffer size, you'll need to calculate them yourself.

the size of vertices = sizeof(vertices[0]) * numVerts
the size of vertices = sizeof(vertices[0]) * numVerts

No. The sizeof an array type is the number of elements in the array, NOT the number of elements in the array multiplied by the size of individual elements in the array.

You will want to replace that with simply numVerts.
Last edited on
Ok, tried it again with a simplified example of a 3-vertex triangle, using "number of vertices (three)" in place of
 
sizeof(vertices)

Still no dice. Still works fine, as long as I'm using a standard "compiletime" array. Here's what I've tried:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CUSTOMVERTEX *vertices = new CUSTOMVERTEX[3];
	//CUSTOMVERTEX vertices[3]; <<--"working" version
	
	vertices[0].pos = D3DXVECTOR3(-1.0f, 0.0f, 0.0f);
	vertices[0].COLOR = RED;
	vertices[1].pos = D3DXVECTOR3(0.0f, 2.0f, 0.0f);
	vertices[1].COLOR = GREEN;
	vertices[2].pos = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
	vertices[2].COLOR = BLUE;

	
	d3ddev->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);
	VOID* pVoid;
	v_buffer->Lock(0, 0, (void**)&pVoid, 0);
	//memcpy(pVoid, vertices, sizeof(vertices)); <<--the "working" version
	memcpy(pVoid, vertices, 3); <<--is this what you meant?
	v_buffer->Unlock();
	
	short indices[] =
	{
		0,1,2,
	};
	
	d3ddev->CreateIndexBuffer(3 * sizeof(short), 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &i_buffer, NULL);
	i_buffer->Lock(0, 0, (void**)&pVoid, 0);
	memcpy(pVoid, indices, sizeof(indices));
	i_buffer->Unlock();
	
	
	vertices = nullptr;
	delete[] vertices;
Last edited on
Ok, I think I got it.
The problem was, in fact in the v_buffer loader.
The proper format for the dynamic array "vertices" is
 
memcpy(pVoid, vertices, sizeof(CUSTOMVERTEX) * numVerts);


Thanks for all the Help! VERY much appreciated, and I learned a few things along the way!
Cheers!
Topic archived. No new replies allowed.