0

この状況でポインタがアドレスを変更する理由を理解できないようです:

int *load(FILE *fp, int * vector, int w, int h){
    //other coding
    int array[w][h];
    int *ptr = &array;
    return ptr;
}

main(){
    //other coding
    int *ptr = load(file, vector, w, h);
    printf("%d ", *(ptr));
    printf("%d ", *(ptr));
}

私の最初は00000010printf("%p ", *(ptr));を出力します

私の秒では、printf("%p ", *(ptr));それは0028fc6cを出力します

確かに、最初の値で値を印刷する"%d"と、2番目の値は適切ではありません。

4

4 に答える 4

1

返されるarrayアドレスはload()、その関数のローカル変数です。スタックに割り当てられ、後続の関数呼び出しで再利用されるため、アドレスを返さないでください。

表示されている変更された値は、s への呼び出しprintf()がスタックのその場所を更新しているためです。

于 2013-10-08T05:54:42.023 に答える
0

まず、ポインターを出力しているのではなく、ポインターが指す値を出力しています。これが単項演算子の*機能です。指定された値にアクセスできます。したがって、あなたが観察したものは、何らかの「アドレス」が変更されたことを意味するものではありません。プログラム内のアドレスを検査していません。

第二に、上記はおそらく、変更されるのはポインターではないことを意味します。変化するのはポイント値です。実際、関数から返されたポインターは、無効なメモリ位置 (存在しない以前のローカル配列のサイト) を参照しています。無効なメモリ位置が明白な理由なしに値を変更するという事実に異常はありません。これを未定義動作と呼びます。プログラムがクラッシュした可能性がありますが、クラッシュではなく純粋に運が良かったため、「不可解に」変化する値が得られました。

第 3 に、寛大なコンパイラによってコードが「コンパイル」されたとしても、「コンパイル エラー」などの制約違反がまだ含まれています。この初期化は無効です

int *ptr = &array;

&array値の型はint (*)[w][h]です。型のポインタの初期化には使用できませんint *。コンパイラがそれについてあなたに言ったと確信しています。コンパイラが発行する診断メッセージに注意を払う必要があります。

于 2013-10-08T06:05:19.717 に答える