Reputation: 41
I have a 2D array organized as
float vertices[3][3]
In one iterative loop of my program, I see in my debugger that the the array fills up as so:
vertices[0] = {-1, -1, 1}
vertices[1] = {-1, -.5, .5}
vertices[2] = {-.5, -1, .5}
I then pass the three vertices to my triangle class.
Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(*t);
The triangle constructor is coded as so:
Triangle::Triangle(float *a, float *b, float *c)
{
memcpy(v1, a, sizeof(a));
memcpy(v2, b, sizeof(b));
memcpy(v3, c, sizeof(c));
}
My debugger now shows
v1 = {-1, -431602080, -431602080}
v2 = {-1, -431602080, -431602080}
v3 = {-.5, -431602080, -431602080}
Debugger also shows that a/b/c are only 1 element long? So apparently only the first element of the array is being passed?
Upvotes: 0
Views: 981
Reputation: 593
Aside from the other solutions, I want to point out that your code has a memory leak:
Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(*t);
When you push_back(*t)
, you are pushing a copy of the allocated object at *t
, not a copy of the pointer t
. The vector internally allocates space for another Triangle
and copies the given object into it. After this code, that pointer is lost and the allocated object is orphaned/leaked.
If you mean to keep your triangles as individually-allocated objects, then triangles
should be a vector<Triangle *>
and the code should look like this:
Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(t);
If you mean to keep triangles
as a vector<Triangle>
, then you want something more like this:
Triangle t(vertices[0], vertices[1], vertices[2]);
triangles.push_back(t);
Or, if your compiler/stl implementation supports vector::emplace_back()
, this is even simpler:
triangles.emplace_back(vertices[0], vertices[1], vertices[2]);
Which does the construction directly into the new entry in the vector.
Upvotes: 0
Reputation: 218238
An alternative is to expected fixed size float array:
Triangle::Triangle(const float (&a)[3], const float (&b)[3], const float (&c)[3])
but passing size
or using std::array<float, 3>
or std::vector<float>
seems simpler.
Upvotes: 0
Reputation: 9619
In your case, sizeof(a)
will give you the size of the pointer, not the data it points to. This is because a
is a float
pointer!
Do this: Pass number of elements (3 in your case) as a parameter:
Triangle::Triangle(float *a, float *b, float *c, int numElements)
{
memcpy(v1, a, sizeof(a) * numElements);
memcpy(v2, b, sizeof(b) * numElements);
memcpy(v3, c, sizeof(c) * numElements);
}
Upvotes: 0
Reputation: 409442
The problem here is your use of the sizeof
operator, because once an array has decayed to a pointer it looses all size information, and in the function doing e.g. sizeof(a)
will only give you the size of the pointer and not what it points to.
There's an easy way to solve these problems in C++, and that is to use either std::vector
or std::array
instead. If you for some reason don't want to use those handy classes, then you need to pass the size to the function in some way, like for example an argument or as a template parameter.
Upvotes: 0
Reputation: 2357
sizeof(a)
is actually
sizeof (float*)
which is not 3x float, it is 1 pointer. Pass additional parameter size_t number_of_members_in_array and replace
memcpy(v1, a, sizeof(a));
with
memcpy(v1, a, sizeof(*a) * number_of_members_in_array);
Triangle::Triangle(float *a, int numA, float *b, int numB, float *c, int numC)
{
memcpy(v1, a, sizeof(float) * numA);
memcpy(v2, b, sizeof(float) * numB);
memcpy(v3, c, sizeof(float) * numC);
}
Upvotes: 3