指针操作和类型转换

时间:2016-03-14 00:25:36

标签: c pointers macros malloc

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

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

此处bpvoid指针。

GET_HDR(bp)用于获取HEADER的内容,该内容是在空指针bp之前存储的4字节块。这里第一个宏取空指针bp,将它转换为int并减去1以将指针移回4字节,使其指向HEADER块,然后取消引用指针以赋值{{ 1}}阻止。

但是第二个宏怎么做呢?指针如何被操纵以达到HEADER阻止?

2 个答案:

答案 0 :(得分:3)

宏可能假定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) */
    )
)

答案 1 :(得分:1)

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

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

当你施放(int *)(bp) - 1时,你要求任何系统上的指针 - 之前 - bp(或4-bytes之前bp 4-byte int - 涵盖大多数系统)。但是,(char **)(bp) - 1上的x86_64投标会在8-bytes之前询问bp之前的指针4-bytesx86之前的6.5.6。这可能会导致问题。

您必须小心地在宏中转换为不同类型,并避免违反严格别名规则。请参阅C标准的6.5.7typedef void (^ saveBlock_block_t )(WhateverYourReturnObjectType *obj); @interface DetailTableViewCell : UITableViewCell - (void)configureCell:(NSString *)textFieldVal cellBlock:(saveBlock_block_t)cellBlock; @end 部分。这里没有涉及,但如果您依赖宏中的多个强制转换,则可能会掩盖违规行为。

相关问题