C语言 指针操作和类型强制转换



从 malloc 的自定义内存分配器中,考虑以下两个宏:

#define GET_HDR(bp) (*(int *)((int *)(bp) – 1))
#define GET_HDR(bp) (*(int *)((char **)(bp) – 1))

这里bp是一个void指针。

GET_HDR(bp) 用于获取 HEADER 的内容,该 是存储在 void 指针bp之前的 4 字节块。在这里,第一个宏获取 void 指针 bp,将其类型转换为 int 并减去 1 以返回指针 4 个字节,以便它指向HEADER块,然后取消引用指针以给出HEADER块的值。

但是第二个宏是如何做到的呢?如何操纵指针到达HEADER块?

可能假定char *的大小与int相同。

(
    *(int *)(       /* Treat result as pointer to int and dereference */
      (char **)(bp) /* bp is cast to a pointer to (char *) */
      – 1           /* take bp back sizeof(char *) bytes (presumably also 4) */
    )
)
指针

就是指针,但指针算术取决于type。如果 intchar * 的大小不同,则在减去 1 时,宏在内存中的偏移量不会相同。然后再次强制转换为*(int *)以获取值时,最终可能会得到不同的结果。

使用指针算术时必须小心。如果系统上的intchar *不同,就会出现问题。例如,在x86_64指针大小为8-bytesint的大小为4-bytes。在x86指针大小为4-bytesint的大小也4-bytes

当您投(int *)(bp) - 1时,您要求在任何具有4-byte int的系统上bp之前(或bp之前4-bytes指针 - 涵盖大多数系统)。但是,在x86_64上投(char **)(bp) - 1会要求在bp之前8-bytes指针,而x864-bytes之前。这可能会导致问题。

在宏中强制转换为不同类型时还必须小心,并避免违反严格的别名规则。请参阅 C 标准的第 6.5.6 节和第 6.5.7 节。这里不涉及,但如果您依赖于宏中的多个强制转换,您可能会掩盖违规行为。

相关内容

  • 没有找到相关文章

最新更新