1

这是我遇到的一个非常基本的内存地址问题:

这是我的片段:

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

输出如下:

指针 i = 0x7fff5fbff700,i = 5fbff700,(i+1) = 0x7fff5fbff704,(i+1) = 5fbff704

这是一个 32 位内核。

我真正不明白的是:
地址0x7fff5fbff700和地址0x7fff5fbff704应该相差 32 位或 4 个字节。

如果我将地址中的每个“元素”0x7fff5fbff700视为 1 个字节,那么是的,我可以看到这两个地址如何相差 4 个字节,但如果是这种情况,那么地址0x7fff5fbff704将是 12*4 = 48bytes 。这怎么可能呢??

我在Linux中运行它,这就是我得到的:

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

如果我尝试打印 (i+1)-1,它总是给出 0x1

但我不明白 0xffff 82cc 和 0xffff 82d0 相差 32 位或 4 个字节!

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

请解释

4

2 回答 2

5

这很简单。地址指向内存中的一个字节。将地址加 1,即可获得内存中下一个字节的地址。

指针知道它们指向的值的大小,因此当您将 1 添加到 an 时,int*它实际上会将包含的地址增加 4(以适应 32 位(4 字节)整数)。

0x7fff5fbff700特定字节的地址也是如此(或者在int*32 位 int 的情况下)。 0x7fff5fbff704 = 0x7fff5fbff700 + 4,所以0x7fff5fbff704指向第一个字节之后的第 4 个字节(或下一个 32 位整数)。

同样,0xffff82d0 = 0xffff82cc + 4寻址位置相隔 4 个字节(32 位)。

图表可能会有所帮助。将内存视为一个大字节列表,每个字节都有自己的地址。所以一小部分内存看起来像(网格中的每个单元格都是一个位,字节的地址在右边):

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

因此,在您的代码中int,值为 0x7fff5fbff700 的指针指向 `32 位 int,它存储在内存位置 0x7fff5fbff700、0x7fff5fbff701、​​0x7fff5fbff702 和 0x7fff5fbff703 中。那是 4 个字节,总共 32 位。

当您将 1 加到指针上时,它实际上将地址增加 4,因此指针然后存储下一个 32 位整数 (0x7fff5fbff704) 的第一个字节的地址。

于 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 个字节。

十六进制数学的工作原理与十进制数学几乎相同,除了数字是 0123456789abcdef,表示值 0..15 十进制。因此,例如3 + 7 = a, a + 1 = b, a + a = 14。所以d0-cc,如果从 移除 开始c0d0我们10-c就剩下来计算了。那是十进制的 16-12,等于 4。

于 2013-01-10T00:28:21.690 回答