2016-05-04 9 views
0

に影響を与えているようだ - ライン77でhttps://github.com/ryu577/base/blob/master/numerical/c/NumericalRecipiesCode/src/ch05/tst5.cC無関係な機能は、私は私のCプロジェクトのいくつかの本当に奇妙な行動見てい単純な配列の初期化

を、私はライン13上にある「testFn」のルーチンのいずれかを実行し、I以下にも含まれています。私は関数へのポインタを渡すことでこれを行います。

float testFn(float x) 
{ 
    return x*x; 
} 

次に、ライン87上に、私は単にCにおける数値レシピから定型ルーチンに基づいて、フロートの1Dアレイを初期化することを試みる:

float *c1; c1 = vector(0, n1); 

「ベクター」機能は非常に単純であり、ここに含ま:

float *vector(long nl, long nh) 
/* allocate a float vector with subscript range v[nl..nh] */ 
{ 
    float *v; 
    v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); 
    if (!v) nrerror("allocation failure in vector()"); 
    return v-nl+NR_END; 
} 

、私は私の "ベクター"(float配列 - C1)内のエントリを印刷するとき、これは私が得るものです -

12.00 12.00 12.00 0.00 0.00 

どうにかして、最初の3つの位置に12を入れることにします。しかし、実際に興味深いのは、これらの数値がtestFnをどのように定義するかに依存するということです。私のようにそれを定義した場合たとえば、:

112.00 110.04 109.04 108.53 0.00 

しかし、事は、ベクターの作成と初期化がtestFnでとは何の関係もなかったということです。

float testFn(float x) 
{ 
    return x*x*x; 
} 

私はその後、C1のエントリを取得しますすべて。では、このようにしてその値にどのように影響を与えることができるのでしょうか?それは解放されていないいくつかのメモリブロックに関連していますし、値は新しい配列に流出していますか?

+1

あなたは*初期化された*ベクトルではありません。その内容は、そこに何かを保存するまでは定義されていません。これらの値を初期化する前にこれらの値を読み取ろうとするのはUBです。 –

+0

また、以前の質問に対するコメントや提案、特に人々があなたを助けてくれるようにするには、通常[mcve]を提供する必要があるアドバイスを書き留めてください。 –

+0

@PaulR - ありがとう。コードのどの部分もこの動作を引き起こしていた可能性があるため、ここでは最小限の例を提供することは非常に難しいと感じました。私は今、ベクトルを初期化していないが、testFnがデフォルト値に影響を与える理由について興味があることを理解しています。 –

答えて

3

malloc()アレイの内容を初期化しない。これは、このブロックに何かがある可能性があることを意味します - 浮動小数点、整数、またはごみの場合は、以前の操作から残った数値です。これは、関数の中で配列を宣言するときにも起こります。

通常、割り当てられたブロックをすべて消去すると、計算時間を無駄にしたくなくなります。なぜなら、使用しているブロックを上書きするためです。目的の動作を得るには、配列を割り当てた後でループを使用して初期化します。

最後に、初期化されていないメモリをfloatとして読み出すと、プログラムで未定義の動作が発生することがあります。詳細な説明は、read before write is undefined with malloced memory?の質問を参照してください。

+1

これは予想される動作です。私はC#とJavaに慣れていますが、この種のことは起こりません。 –

+1

代わりに 'calloc()'を使うこともできますが、まずmallocとcallocのマニュアルページを読むことをお勧めします。 –

+0

'calloc()'は整数のために働く可能性のあるメモリをゼロにしますが、浮動小数点変数に対しては必ずしも必要ではありません。 – alk

関連する問題