I ran into unexpected behavior with a function I wrote to compute the average point for a set of 3D points.
static inline Point3d
average_vertex_position( Vertex vertices[], int nPoints )
{
Point3d average = { 0.0, 0.0, 0.0 }; // Must be there to avoid accumulation
Point3d point;
int i;
for ( i = 0; i < nPoints; i++ )
{
point = vertices[i].position;
average.x += point.x;
average.y += point.y;
average.z += point.z;
}
average.x /= (double) nPoints;
average.y /= (double) nPoints;
average.z /= (double) nPoints;
return average;
}
// ...
Point3d average;
// ...
for ( j = i; j < nVertices; j++ )
{
// ...
average = average_vertex_position( vertices, nVertices );
// ...
}
For each iteration the return value of average_vertex_position would accumulate unless I added explicitly the initialization Point3d average = { 0.0, 0.0, 0.0 };.
If the previous return value was Point3d( 10, 0, 20 ) and the next run should have returned Point3d( 20, 10, 0 ) it would instead return an accumulated result Point3d( 30, 10, 20 ).
Originally I had just Point3d average; assuming all the member values (double values) would be initialized to 0.0. I also assumed average would be in this initial state between each call. I don’t understand why I need to explicitly initialize it?
I trimmed out the code I didn’t think was relevant – but I could be wrong, in which case I’ll update if it doesn’t hold enough information.
That is normal with
autovariables – they are not initialized to 0 if not explicitly stated.The fact that the old values are reused is pure coincidence, as you don’t have any other function calls in-between. If you would have them, the memory at the given stack position would be overwritten and your values were different.