需要澄清malloc

时间:2013-02-09 21:17:00

标签: c

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

3 个答案:

答案 0 :(得分:1)

  

我尝试将8字节指针存储在单个字节中

代码中没有单个字节。 rrr是一个指针,*rrr也是如此(因为你将rrr声明为指针指针)。

但是,您几乎肯定会在此处调用未定义的行为。除非sizeof(void *)为1(这是极不可能的!),否则写入*(rrr+5)将超出您分配的内存范围。

答案 1 :(得分:1)

  

单个字节只能保存最多255个值,但是当我打印时   存储在这些字节中的值,值大于255

但是*rrrvoid *,它可能是你机器上的8个字节,并且能够按照定义保存任何对象指针。

此外,由于您只为rrr分配了8个字节,因此超过第一个元素的任何内容 - 分配或读取 - 都是非法的。


您似乎认为分配8个字节会以某种方式在元素之间均匀分配它们,但事实并非如此。在分配rrr指向您可以使用的8个字节后,您可以使用*rrr = malloc...执行此操作。这一切都是正确的和预期的:*rrr是一个空白,因此能够保存任何地址,因此能够保存大于255的东西。

一旦你去rrr + 1或者你进一步踩到未定义的行为,就会发生意想不到的事情。

修改

  

但我认为,如果我打印一个8字节的每个字节值   阻止,任何字节都可以保存值&gt; 255

但你不打印字节!您正在打印指针并将i添加到rrr 将其推进到下一个指针

答案 2 :(得分:1)

由于rrrvoid**rrr+5指向您分配的8字节内存中的40个字节,因为在64位Linux计算机上sizeof(void *) == 8

每当你向C中的指针添加一个整数时,整数总是按(指示)指针指向的任何大小(sizeof(*rrr)来缩放(sizeof(void *)