侵入链接列表的指针算法

时间:2016-01-12 08:58:43

标签: c pointers

我一直在看这个intrusive linked list implementation in C,并且有一些指针运算我似乎无法拼凑在一起。

首先,这个函数和宏启动一个链接节点:

#define LINK_INIT(linkptr, structure, member) \
  link_init(linkptr, offsetof(structure, member))

void link_init(link *lnk, size_t offset) {
  lnk->next = (void*) ((size_t) lnk + 1 - offset);
  lnk->prev = lnk;
}

我理解lnk->next (void*) ((size_t) lnk + 1 - offset)是指向链表中下一个结构的指针,但我不明白为什么添加1允许指针在偏移量是抵消成员的字节数时仍然有效从结构的开头。在struct header definition中,作者说低位被用作表示列表末尾的标记,因此lnk->next指针可以和1一起测试结束:

// All nodes (=next) must be allocated on (at least) two-byte boundaries
// because the low bit is used as a sentinel to signal end-of-list.
typedef struct link {
  struct link *prev; 
  void *next;
} link;

void* link_next(link *lnk) {
  if ((size_t) lnk->next & 1)
    return NULL;
  return lnk->next;
}

我只是想知道为什么这会起作用?我模糊地理解分配边界,但我认为不足以看出为什么这样做。

1 个答案:

答案 0 :(得分:0)

它的工作原理是因为大多数现代架构都是32位甚至64位宽,指针必须在32位或64位块上对齐;在这种情况下,指针的int值必须是32或64的倍数;所以至少它是均匀的。

并非总是如此。仅仅因为指针的int值是奇数,并不意味着指针无效。这取决于架构。

此外,当获得" next"指针,必须执行测试才能返回正确的值:NULL

指针值,额外测试和使用错误指针的风险的错误假设...为什么不首先将指针设置为NULL