1

このコードで、プログラムの実行時に *(ptr + 1) の値が 6 ではなく 1 になる理由が気になります。

#include <stdio.h>

int main (void)
 {
     int *ptr, content = 3;

     ptr = &content;

     *(ptr + 1) = 6;
     *(ptr + 2) = 10;
     *(ptr + 3) = 14;

     int i = 0;

     for (i = 0; i < 4; ++i)
      {
          printf("The address is %p and the content is %d \n", ptr+i, *(ptr+i));
      }

     return 0;
 }

run int 6 が値 1 に変更されたとき。

*(ptr + 1) = 6;

プログラムの出力は次のとおりです。

The address is 0x7fff7b400a88 and the content is 3 
The address is 0x7fff7b400a8c and the content is 1 
The address is 0x7fff7b400a90 and the content is 10 
The address is 0x7fff7b400a94 and the content is 14 

私はそれをvalgrindで実行しましたが、エラーは表示されませんでした.

4

6 に答える 6

4

自分に割り当てられていないメモリを変更しているため、これは未定義の動作です。

関数内のスタック領域が次に使用されるため、変数がその場所に割り当てられる可能性があります。そして、その時点で1です。したがって、出力は 1です。ii

変化する

int content = 3;
ptr = &content;

int content[10] = {3};
ptr = &content[0]; //or ptr = content; but this may be harder to grasp if you are new to C

(ポインタの割り当てを修正してくれた@KeithThompsonに感謝します)

ポインター演算を試しているだけの場合。int10の配列にあるスタック空間全体を所有しているので、これは機能します。

于 2013-01-03T02:49:09.367 に答える
2

このプログラムは不正なポインタを介してメモリを変更します。ほとんどの場合、ポインターはiたまたま格納されている場所を指しているためi、その時点での値を出力します。

バグを修正すれば、謎は消えます。バグのあるプログラムを理解することは、正しいプログラムを理解することよりもはるかに複雑です。

于 2013-01-03T02:49:21.537 に答える
1

のために取っておいたメモリに変数を書き込んでいるようですi。とにかく、明示的に割り当てていないデータを上書きするべきではないため、なぜそれが重要なのかわかりません。

于 2013-01-03T02:50:36.273 に答える
0
*(ptr + 1) = 6;
*(ptr + 2) = 10;
*(ptr + 3) = 14;

上記のステートメントでスタックの破損が発生していますが、これは未定義の動作です。あなたのプログラムは *(ptr + 0) だけにアクセスする権利を持っているので、幸運にもクラッシュは起きていません。

そして、なぜ*(ptr + 1)印刷1しているのかというと、スタックで宣言されている次の変数を指しています。つまり、指しているということiです。*(ptr + 1)ループの前に印刷forしようとすると、0が印刷されます。また、そのアドレスを印刷しようとするiと、 と同じになります(ptr + 1)

ループの後int i = 0;と前に、以下のようにさらに 2 つの変数をfor宣言してから実行します。1014*(ptr + 2)*(ptr * 3)

int i = 0;
int x = 2;
int y = 2;

printf("%d", *(ptr + 1)); //this will print 0

for (i = 0; i < 4; ++i)
{
....
}

解決

問題の修正は、content以下のようにサイズ 4 の配列として作成することです。

...
int *ptr = NULL;
int content[] = {3, 0, 0, 0};
ptr = content;
...
于 2013-01-03T09:08:12.463 に答える
0

割り当てていないメモリを指すように ptr を移動し、コンパイラがそこに置くものをすべて取得します。

于 2013-01-03T02:50:45.890 に答える
0

あなたのコードは、配列の一部として割り当てられていないアドレスに書き込んでいるため、未定義の動作を呼び出しています。何でも起こり得るし、それは正しい。

最も可能性が高いのは、変数iが 0x7FFF7B400A8C に格納されており、出力される内容が変更されていることです。

于 2013-01-03T02:50:46.650 に答える