2016-12-26 11 views
1

私はちょうど1ヶ月前にC言語でプログラミングを始めました。私はいくつかの異なるソースからそれについて読んだことがあるにもかかわらず、明らかにメモリ割り当てについて何かを理解していません。初心者レベルのメモリ割り当て

誰かがこの簡単な例が私がクラッシュした理由を説明できたら、私はとても感謝しています。 (悪い英語で申し訳ありません)

void test(double *x) 
{ 
    x = (double *)malloc(2 * sizeof(double)); 
    x[0] = 2; 
    x[1] = 3; 
} 

int main() 
{ 
    double *x = NULL; 
    test(x); 

    printf(" %f", x[0]); //this is where it crashes with no message 
} 
+4

'C++'タグを削除してください。 *我々は 'c' *と戦っている。 < - ジョーク。ライトアップ。しかし真剣に、 'C++'タグを削除するべきです。最近は2つの異なる言語です。 –

+0

デバッガと2つのブレークポイント。 'test'の終わりに1つ、' main'の 'printf'に1つは、両方の場合に' x'に格納されたアドレスを調べると問題を実証します。ヒント: 'test ='の 'x = ... 'という代入は、呼び出し側(' main')に対して* nothing *を意味し、 'x'は変更されません。 – WhozCraig

+0

1)呼び出し元プログラムのポインタを新しいアドレスを指すように変更するには、 'malloc()'の戻り値をキャストしないでください。ポインタはポインタへのポインタとして渡されなければなりません。 I. 'test(&x);')関数testには署名が必要です: 'void test(double ** x)' '**'に注目してください。 '(* x)[0] = 2;' – user3629249

答えて

3

問題はメモリ割り当てではありません。それはCの値渡しのパラメータである。あなたの関数はメモリを割り当てますが、渡されたパラメータを更新することはできません。アドレスだけではなく、その値を持つからです。

私は正確にポインタが更新されない理由として知らないが、あなたはポインタで構造体を渡すことだった場合、それはあなたのようなポインタを更新する必要があり、他の賢明を働くだろう

void test(double **x) 
{ 
    *x = (double *)malloc(2*sizeof(double)); 
    (*x)[0] = 2; 
    (*x)[1] = 3; 
} 
int main() 
{ 
    double *x = NULL; 
    test(&x); 

    printf(" %f", x[0]); //this is where it crashes with no message 
} 
-1

をお試しくださいそう。 また、割り当てるポインタがvoid型の場合にのみデータ型をキャストする必要があります。

double *test() 
    { 
     double *x = malloc(2*sizeof(double)); 
     x[0] = 2; 
     x[1] = 3; 
     return x; 
    } 

int main() 
{ 
    double *x = test(); 


    printf(" %f", x[0]); //this is where it crashes with no message 
} 
+0

関数の引数を渡して受け取りました。 ? –

+0

それ以外の場合は、それを行う唯一の方法です。あなたの好みに関係なく、ポインタへのポインタを渡す必要があります。 –

+0

ああありがとうxD私は関数の引数を設定するのを忘れていました! –