I have a pointer to an array of structs like so:
class Terrian {
...
private:
Vector *terrian_vertices;
...
}
And the data for the pointer is generated in the “construct_vertices” function
Terrian::Terrian(int width, int height) {
this->width = width;
this->height = height;
std::cout << "Width: " << width << " Height: " << height << "\n";
std::cout << "Vertices\n";
construct_vertices();
std::cout << "Element\n";
construct_elements();
std::cout << "Buffers\n";
construct_buffers();
}
void Terrian::construct_vertices() {
terrian_vertices = new Vector[width * height];
std::cout << "Generating data\n";
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = x + y * width;
Vector *pos = new Vector((GLfloat)x, 0.0f, (GLfloat)-y);
memcpy(pos, terrian_vertices, sizeof(Vector) * index);
std::cout << terrian_vertices[index].x;
Color *color = new Color(0, 255, 0);
memcpy(color, terrian_colors, sizeof(Color) * index);
}
}
}
Here is the program’s output (all I do in the main function is instantiate the object)
Width: 32 Height: 32
Vertices
Generating data
5.2349e-039
Process returned -1073741819 (0xC0000005) execution time : 10.073 s
Press any key to continue.
The program crashes when the first pointer is copied to the array, and the output for ‘x’ should be 0. Which is puzzling. Does anyone know what is causing this to happen? If so, is there a better way to allocate structs dynamically – without using memcpy?
The use of
memcpyis incorrect. Any reference documentation will tell you that.The first parameter is a pointer to the destination, which would be
indexelements into theterrian_verticesarray:terrian_vertices + index.The second parameter is a pointer to the source, which is
pos.(If you’re curious, the reason the destination comes before the source is because it parallels the assignment operator:
destination = source)The third parameter is the amount of data to copy, which in your case would just be
sizeof(Vector): it’s just oneVectorit needs to copy, notindex.Misusing
memcpylike the code does easily leads to undefined behaviour, which is luckily manifesting as an error.Yes. Don’t manage memory yourself: use
std::vectorand normal copy semantics.Notice how now there’s no
newanywhere in sight. This solves another issue with the original code: it was leaking one instance ofVectorand one ofColorper loop iteration.