2012-03-12 9 views
0

3Dポイントの集合の平均点を計算するために書いた関数で予期しない動作が発生しました。各反復について非静的変数の累積戻り値は?

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); 
    // ... 
} 

Iが明示的に初期化Point3d average = { 0.0, 0.0, 0.0 };を加えない限り、average_vertex_positionの戻り値が蓄積します。

前回の戻り値がPoint3d(10, 0, 20)で、次の実行がPoint3d(20, 10, 0)を返すはずでしたが、累積結果Point3d(30, 10, 20)が返されます。

元々、すべてのメンバー値(doubleの値)が0.0に初期化されていると仮定して、ちょうどPoint3d average;でした。私はまた、averageが各呼び出しの間にこの初期状態にあると仮定しました。なぜ明示的に初期化する必要があるのか​​分かりません。

私は関連性がないと思われるコードを整理しましたが、間違っている可能性があります。十分な情報がない場合は更新します。

答えて

3

これは通常、autoの変数です。明示的に指定されていない場合は、0に初期化されません。

古い値が再利用されるという事実は、他の関数呼び出しをしていないので、純粋な一致です。もしそれらを持っていれば、与えられたスタック位置のメモリは上書きされ、あなたの値は異なっています。

+0

私はCと変数を読んでいたときに逃してしまったことがありました。私は 'int'と' double'は常に0に初期化されていると思っていました。明らかに明確な開始が最も安全です。 – thomthom

+0

定義に 'struct'のデフォルト値を定義することはできますか?または私が掲示した例のように変数を作成するたびにそれを行う必要がありますか? – thomthom

+0

これはn00bの質問だった気がしていた... – thomthom