在池的实现中从void *转换为char *

时间:2016-05-21 06:14:02

标签: c pointers memory void-pointers

在基本池的实现中我有这样的东西(我将简化代码以使其更清晰)

struct unit_header{
  struct unit_header* next, prev;
};
int number_of_units = 10
int unit_size = 5;
int full_block = number_of_units*(unit_size+sizeof(struct unit_header));

void* p_mem_full_block = malloc(full_block);

//iterate all units of mem_full_block
for (int i = 0; i< number_of_units; i++){
  //pointer to each unit
  struct unit_header* p_units = (struct unit_header*)((char*)p_mem_full_block + i*(unit_size+sizeof(struct unit_header)));
  //.... some pointers stuff....
}

我知道这部分(下面)用于遍历mem_block的所有单元......

i * (unit_size+sizeof(struct unit_header))

我没有得到这一部分:

  

(字符*)p_mem_full_block

装置。为什么我必须进行此char *转换?

1 个答案:

答案 0 :(得分:1)

这是因为根据C标准你无法添加,减去void *的任何内容;但是为char *定义了加法和减法,它们按指定的字节数推进指针。

但是,除非-Wpointer-arith-Wpedantic启用,否则GCC允许无效指针算法作为没有警告的扩展名。

此外,整个操作看起来不太方便,因为unit_header结构的对齐要求可能与unit_size的倍数不同。实际上,5的unit_size将导致问题,并且在许多处理器上,这样的代码将编译但在运行时崩溃,因为指针(prevnext)未对齐,例如,实现可能需要一个可被4或8整除的地址,而代码将允许其间的任何数字。但是,x86本身通常并不关心错误的对齐。

即。 两种指针类型之间的转换会产生错误对齐的结果根据C11具有未定义的行为。