1

これは私が持っている非常に基本的なメモリアドレスの質問です:

これが私のスニペットです:

int *i = &a[0];
printf("ptr i = %p, i = %x, (i+1) = %p, (i+1) = %x\n", i, i, i+1, i+1);

出力は次のとおりです。

ptr i = 0x7fff5fbff700、i = 5fbff700、(i + 1)= 0x7fff5fbff704、(i + 1)= 5fbff704

これは32ビットカーネルです。

私が実際に得られないのは次のとおりです。
アドレス0x7fff5fbff700とアドレス0x7fff5fbff704は32ビットまたは4バイト異なるはずです。

アドレスの各「要素」0x7fff5fbff700を1バイトと見なすと、そうです。2つのアドレスが4バイト異なることがわかりますが、その場合、アドレス0x7fff5fbff704は12 * 4=48バイトになります。どうしてそれも可能ですか?

私はそれをLinuxで実行しました、そしてこれは私が得るものです:

ptr i = 0xffff82cc、i = ffff82cc、(i + 1)= 0xffff82d0、(i + 1)= ffff82d0

(i + 1)-1を印刷しようとすると、常に0x1になります

しかし、0xffff82ccと0xffff82d0の32ビットまたは4バイトの違いがわかりません。

0xffff82cc = FFFF 1000 0010 1010 1010
0xffff82d0 = FFFF 1000 0010 1011 0000

説明してください

4

2 に答える 2

5

とても簡単です。アドレスはメモリ内のバイトを指します。アドレスに1を追加すると、メモリ内の次のバイトのアドレスが取得されます。

ポインターは、ポインターが指している値のサイズを知っているため、ポインターに1を加算するint*と、実際には4に含まれるアドレスがインクリメントされます(32ビット(4バイト)整数に対応するため)。

特定0x7fff5fbff700のバイトのアドレスも同様です(またはint*32ビット整数の場合)。 0x7fff5fbff704 = 0x7fff5fbff700 + 4、したがって0x7fff5fbff704、最初のバイトの次の4番目のバイト(または次の32ビットint)を指します。

同様に0xffff82d0 = 0xffff82cc + 4、アドレス指定された場所は4バイト(32ビット)離れています。

ここでは図が役立つかもしれません。メモリは、それぞれが独自のアドレスを持つバイトの大きなリストと考えてください。したがって、メモリのごく一部は次のようになります(グリッド内の各セルは1ビットで、バイトのアドレスは右側にあります)。

|               |
|               |
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff6ff
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff700
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff701
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff702
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff703
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff704
+-+-+-+-+-+-+-+-+
| | | | | | | | |   <-  0x7fff5fbff705
+-+-+-+-+-+-+-+-+
|               |
|               |

したがって、コードでは、int値0x7fff5fbff700のポインタは、メモリ位置0x7fff5fbff700、0x7fff5fbff701、​​0x7fff5fbff702、および0x7fff5fbff703に格納されている`32ビットintを指します。これは4バイトで、合計32ビットです。

ポインタに1を追加すると、実際にはアドレスが4インクリメントされるため、ポインタは次の32ビット整数(0x7fff5fbff704)のfirxtバイトのアドレスを格納します。

于 2013-01-10T00:19:29.133 に答える
4

「これは32ビットカーネルです。」

いいえ、そうではありません。ポインタは64ビットであるため、明らかに32ビットカーネルを実行することはできません。を入力uname -aしてみてください。名前のどこかにx86-64が表示されます。32ビットカーネルでは、ポインタが8桁を超えることはなく、値の長さは12=48ビットです。誰も聞いたことのない48ビットプロセッサを持っていない限り、おそらく64ビットプロセッサです。

ポインタの違いは4バイトです。

 0x7fff5fbff704
-0x7fff5fbff700
---------------
 0x000000000004

同じことがd0-ccの例にも当てはまり、4バイト離れています。

16進数の計算は、10進数の0..15の値を表す0123456789abcdefである点を除いて、10進数の計算とほとんど同じように機能します。したがって、たとえば3 + 7 = a、、、。したがって、から削除することから始める場合は、計算する必要があります。これは10進数で16〜12であり、4になります。a + 1 = ba + a = 14d0-ccc0d010-c

于 2013-01-10T00:28:21.690 に答える