2013-01-10 43 views
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字节的每个“元素”,然后是的,我可以看到两个地址由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 

请解释

+0

甚至不知道这意味着什么......这是什么意思? – user999755

+3

谢谢...我已经接受了我以前的问题的答案...我一直感谢已回复的用户...没有意识到我应该有upvoted或接受..谢谢 – user999755

+2

您的二进制值是错误的顺便说一句。 '82cc' ='1000 0010 1100 1100'和'82d0' ='1000 0010 1101 0000' – JasonD

回答

4

“这是一个32位内核。”

不,它不是。你的指针是64位的,所以你显然无法运行32位内核。尝试输入uname -a,它应该显示名称中某处的x86-64。在32位内核中,指针永远不会超过8个十六进制数字,您的值是12 = 48位长。除非你有一个别人没有听说过的48位处理器,否则它可能是64位处理器。

你的指针之间的差是4个字节:

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

同样适用于您的D0-CC例如,它是除了4个字节。

十六进制的数学工作几乎一样的十进制数学,除了数字是ABCDEF,代表值0..15小数。因此,例如3 + 7 = aa + 1 = ba + a = 14。所以d0-cc,如果开始从d0去除c0,我们10-c留下来计算。这是十进制的16-12,它使得4.

5

这很简单。地址指向内存中的一个字节。给地址加1,你得到地址到内存中的下一个字节。

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

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

同样地,0xffff82d0 = 0xffff82cc + 4因此所寻址的位置相距4个字节(32位)。

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

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

所以,在代码中int终场前值0x7fff5fbff700指向存储在存储单元0x7fff5fbff700,0x7fff5fbff701,0x7fff5fbff702和0x7fff5fbff703中的32位整数。这是总共32位的4个字节。

当你给指针加1时,它实际上会将地址加4,这样指针就会存储下一个32位整数(0x7fff5fbff704)的firxt字节的地址。

+0

@DanielFischer - 感谢。固定。 –