基本内存地址混乱

时间:2013-01-10 00:04:35

标签: c pointers memory memory-management kernel

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

这是我的代码:

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个字节,那么是的,我可以看到这两个地址如何相差4个字节,但如果是这样,那么地址0x7fff5fbff704将是12 * 4 = 48字节。这怎么可能呢??

我在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

请解释

2 个答案:

答案 0 :(得分:5)

这很简单。地址指向内存中的一个字节。将1添加到地址,然后获取内存中下一个字节的地址。

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

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

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

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

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

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

当你向指针添加1时,它实际上将地址递增4,所以指针然后存储下一个32位整数(0x7fff5fbff704)的firxt字节的地址。

答案 1 :(得分: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 = aa + 1 = ba + a = 14。所以d0-cc,如果从c0移除d0开头,我们还需要10-c来计算。这是十六进制的16-12,它是4.

相关问题