我在64位linux,内核2.6.x上有以下代码。据我所知,第一个malloc rrr=malloc(8)
在堆上分配8个字节,而rrr现在包含这8个字节的起始地址的值。然后,我做了一些疯狂的事情。我尝试将8字节指针存储在单个字节中,如*rrr = malloc(8)
所示。然后我在第5个字节做同样的事情。单个字节只能保存最多255个值,但是当我打印存储在这些字节中的值时,这些值大于255.您能解释一下吗?
#include <stdlib.h>
#include <stdio.h>
void ** rrr;
int main(int argc, char ** argv)
{
rrr = malloc(8); // rrr should point to the starting address of an 8 byte block
*rrr = malloc(8);
*(rrr+5) = malloc(8);
for(int i =0;i< 8;i++)
printf("*rrr%d: %p\n", i, *(rrr+i)); // should print what is stored in each byte
return 0;
}
以上一次运行
*rrr0: 0x9ae030
*rrr1: (nil)
*rrr2: (nil)
*rrr3: 0x21
*rrr4: (nil)
*rrr5: 0x9ae050
*rrr6: (nil)
*rrr7: 0x21
答案 0 :(得分:1)
我尝试将8字节指针存储在单个字节中
代码中没有单个字节。 rrr
是一个指针,*rrr
也是如此(因为你将rrr
声明为指针指针)。
但是,您几乎肯定会在此处调用未定义的行为。除非sizeof(void *)
为1(这是极不可能的!),否则写入*(rrr+5)
将超出您分配的内存范围。
答案 1 :(得分:1)
单个字节只能保存最多255个值,但是当我打印时 存储在这些字节中的值,值大于255
但是*rrr
是void *
,它可能是你机器上的8个字节,并且能够按照定义保存任何对象指针。
此外,由于您只为rrr
分配了8个字节,因此超过第一个元素的任何内容 - 分配或读取 - 都是非法的。
您似乎认为分配8个字节会以某种方式在元素之间均匀分配它们,但事实并非如此。在分配rrr
指向您可以使用的8个字节后,您可以使用*rrr = malloc...
执行此操作。这一切都是正确的和预期的:*rrr
是一个空白,因此能够保存任何地址,因此能够保存大于255的东西。
一旦你去rrr + 1
或者你进一步踩到未定义的行为,就会发生意想不到的事情。
但我认为,如果我打印一个8字节的每个字节值 阻止,任何字节都可以保存值&gt; 255
但你不打印字节!您正在打印指针并将i
添加到rrr
将其推进到下一个指针。
答案 2 :(得分:1)
由于rrr
是void**
,rrr+5
指向您分配的8字节内存中的40个字节,因为在64位Linux计算机上sizeof(void *) == 8
。
每当你向C中的指针添加一个整数时,整数总是按(指示)指针指向的任何大小(sizeof(*rrr)
来缩放(sizeof(void *)
)