2

試験勉強をしていて、わかりにくいところに出くわしました。私たちはポインタとメモリの割り当てを扱っています。私はこのビットのコードを持っています:

int * arr[10];
for(i=0; i<5;i++) 
{
    int index = i;
    arr[index] = malloc(sizeof(int*));
    int i = 2 * index;
    *arr[index] = i;
    printf("arr [%d] = %d\n", index, *arr[index]);  /* should be 0, 2, 4, 6, 8 */
}

しかし、私が見つけたのは、 *arr[index] = i を使用する代わりに arr[index] = &i を使用すると、malloc. 私は常に、これら 2 つのことは本質的に同じものであると想定してきましたがmalloc、一方を使用することを保証するには、理解できない重要な違いがあるに違いありません。

なぜmallocここで本当に必要なのか、実際には混乱しています。私はメモリ割り当てにかなり慣れていませんが、いつ使用する必要があるのか​​ よくわかりません(明らかに)。誰かがこれを解決できるかどうか疑問に思っていました。

4

5 に答える 5

4

代わりに次のコードを試してください。

int * arr[10];
for(i=0; i<5;i++) 
{
    int index = i;
    int value = 2*i;
    arr[index] = malloc(sizeof(int*));
    *arr[index] = value;
}

for (i=0; i<5; i++)
{
    int index = i;
    printf("arr [%d] = %d\n", index, *arr[index]);  /* should be 0, 2, 4, 6, 8 */
}

提案した変更を行うと、未定義の動作が発生します。このコードはまだ有効です。

*arr[0]スコープを離れたスタックメモリの一部を指すようになったため、未定義の動作が発生します。


あなたのmallocは実際にはmalloc(sizeof(int)). intではなく にスペースを割り当てていますint *

于 2013-04-02T18:33:29.397 に答える
0

重要な違いの 1 つは、範囲外&iになると存在しなくなることiです (または、そのメモリの一部を別のものに再利用できます...おそらく、含まれていると思っていたものが含まれていない可能性があります)。

于 2013-04-02T18:34:08.880 に答える
0

編集:i以下では、どのように宣言されたかを 示していないと言います。i実際には、ループで使用されている場合は元の値を隠して再宣言します。いずれにせよ、iループの終了時、またはおそらくルーチンの終了時に範囲外になります。

iここでどのように宣言されているかは示していません。ただし、ほとんどの場合、ローカル変数か、メソッドに渡されるパラメーターになります。いずれの場合も、その変数のスペースはスタック上で宣言されます。でその変数のアドレスを取得できますが&i、その変数はメソッドが終了した後になくなり、コードはそれらの値をスタックからポップします。運が良ければ、その価値が必要な限り手付かずのままになるかもしれません。しかし、別のメソッドが呼び出された瞬間に、その値が上書きされて急上昇する可能性があり、プログラムはせいぜい正しく動作しません。

iがグローバルに宣言されている場合、これを回避できます。

さらに、 の値を変更した後でも、同じアドレスを指していますi。ルーチンの最後に、配列のすべての値を出力すると、それらがすべて同じ値 (配列に最後に入力した値) であることがわかります。これは、配列内の各エントリが同じ場所を指しているためです。

于 2013-04-02T18:38:39.483 に答える