2016-08-03 4 views
1
void fun(int* x){ 
    x=(int*)malloc(sizeof(int)); 
    *x = 20; 
} 

int main(){ 
    int y=31; 
    fun(&y); 
    printf(%d,y); 
} 

なぜこのコードはコンパイルに成功するのですか?なぜこのコードは "20"を印刷しないのですか?

コメント:これはEclipseでコンパイルされました 私はこの問題を次のように見ています。 x =(int *)malloc(sizeof(int));

なぜこのプログラムは実行時にクラッシュしませんでしたか?

+6

Cはあなたに十分なロープを与えてくれるからです。 – Idos

+1

削除 'x =(int *)malloc(sizeof(int));'%d \ n "' – BLUEPIXY

+1

mallocの結果をC言語にキャストしてsizeof( * x)をsizeof(int)の代わりに使用します。 – Caw

答えて

6

構文的にコードに問題はないので、コンパイルします。

yのアドレスが関数に渡されます。 yのアドレスを保持する関数内のポインタxは、mallocによって割り当てられた有効メモリのアドレスによって上書きされます。 intの値はyには書き込まれず、ポインタの値が変更されています。その後、関数が返されます(funの割り当てメモリは 'リーク'します)。

メインのyの値は変更されません。

このプログラムの動作が定義されています。

+0

@ user3781974あなたの質問のコードには2つのタイプミスがあります。それらを修正してください。 – 2501

3

ちょっとスタックにプッシュされた変数yのアドレスのコピーを渡しています。あなただけmallocによって返されたアドレスを割り当てることで(ポインタが押された位置で)ポインタを操作し、mainすなわち変数に影響を与えない

*x = 20 

ことにより、そのアドレスに20の値をコピーy

あなたは、これが

void fun(int** x){ 
    *x=(int*)malloc(sizeof(int)); 
    **x = 20; 
} 

int main(){ 
    int *y; 
    fun(&y); 
    printf("%d",*y); 
} 
+2

あなたが与えた例は、 'main'の' y'と 'y' remans _uninitialized_のコピーにメモリが割り当てられているので間違っています。だから基本的に** _未定義の動作_ **を持っています。 – ameyCU

+0

@ameyCUありがとうございます –

+0

なぜ二重間接を使用しますか?どうして 'void fun(int * x){* x = 20; } 'と' int yを渡すだけです。 fun(&y); 'メイン? –

1
x=(int*)malloc(sizeof(int)); //x point to a new addr. 

*x = 20; // change value of new pointer 

助ける行を削除することがあり、それが20を印刷したい場合はx=(int*)malloc(sizeof(int));、それは動作します。

0

main関数の変数yのアドレスを変更するとします。 yのアドレス値を関数に渡すことで、これを行うことはできません。 yのアドレスに割り当て操作が行われていないためです。あなたの例では、アドレスはy(割り当てについては忘れてください)の変数(基本的にはポインタです)はありません。

int* fun(int* x){ 
     printf("Fun before %p - %d\n", x, *x); 
     x = malloc(sizeof(int)); 
     *x = 20; 
     printf("Fun after %p - %d\n", x, *x); 
     return x; // return your new address 
    } 

    int main(){ 
     int *y = malloc(sizeof(int)); 
     *y = 31; 
     printf("Main before %p - %d\n", y, *y); 
     y = fun(y); // assign your new address here 
     printf("Main after %p - %d\n", y, *y); 
     return 0; 
    } 

ただし、上記のコードは行います。

関連する問題