简体   繁体   English

侵入式链表的指针算法

[英]Pointer Arithmetic For Intrusive Linked List

I've been looking at this intrusive linked list implementation in C , and there is some pointer arithmetic that I cannot seem to piece together. 我一直在看C中的这种侵入式链表实现 ,并且有一些指针算法似乎无法组合在一起。

Firstly there is this function and macro which initiate a link node: 首先,此函数和宏会启动链接节点:

#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;
}

I understand that lnk->next (void*) ((size_t) lnk + 1 - offset) is a pointer to the next struct in the linked list, but I don't understand why adding 1 allows the pointer to work still when the offset is number of bytes offsetting the member from the start of the struct. 我知道lnk->next (void*) ((size_t) lnk + 1 - offset)是指向链表中下一个结构的指针,但是我不明白为什么加1时指针仍然可以工作offset是从结构的开头偏移成员的字节数。 In the struct header definition the author says that the low bit is used as a sentinel to signify the end of the list, and so the lnk->next pointer can be &'d with 1 to test for the end: struct标头定义中 ,作者说低位用作lnk->next以表示列表的结尾,因此可以将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;
}

I'm just wondering why this works at all? 我只是想知道为什么这一切可行? I vaguely understand allocation boundaries but I guess not enough to see why this works. 我含糊地理解了分配界限,但我想不足以了解其工作原理。

It works because most modern architectures are 32-bit and even 64-bit wide, and pointers must be aligned on 32-bit or 64-bit blocks; 它之所以起作用,是因为大多数现代体系结构的宽度都是32位甚至64位,并且指针必须在32位或64位块上对齐; in that case, the int value of a pointer is necessarily a multiple of 32 or 64; 在这种情况下,指针的int值必须为32或64的倍数; so at least it is even. 所以至少是偶数

But that is not always true. 但这并不总是正确的。 Just because the int value of a pointer is odd, does not mean that the pointer is not valid. 仅因为指针的int值是奇数,并不表示该指针无效。 It depends on the architecture. 这取决于架构。

Furthermore, when getting the "next" pointer, a test must be performed to return the correct value: NULL . 此外,在获取“下一个”指针时,必须执行测试以返回正确的值: NULL

Incorrect assumption on the pointer value, extra tests, and risks using incorrectly the invalid pointer… Why not setting the pointer to NULL in the first place? 对指针值的错误假设,额外的测试以及错误使用无效指针的风险……为什么不首先将指针设置为NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM