备选 "null" 值
Alternative "null" value
链表末尾的尾指针为空(0)似乎很常见。
如果我想要两个可能不同的“尾巴”怎么办?
我的用例是一个支持二进制补码的大整数表示:我想要一个尾巴对应于“这个数字的其余部分是零”和“这个数字的其余部分是一个”,我可以告诉仅通过执行指针相等将它们分开。
看起来这应该很常见,可以有标准的做法,但很难想出到底要搜索什么。我们只得到一个“禁止的”指针值似乎有点武断(当意外取消引用时会产生 useful-ish 错误)。
选项似乎包括:
- 使用一些任意的第二个值(例如 1 或 0xdeadbeef)。这似乎是邪恶的。一方面,我想它需要对齐?此外,如果 malloc 碰巧在同一地址分配一个真正的链表单元格,我也会有一些模糊的错误。是否有一些内存区域 malloc 保证不使用?
- 使用虚拟 non-zero 大小调用 malloc。这似乎更明智,但理想情况下我会将指针值设置为 const,而不需要初始化。
- 获取任意地址,例如文件中定义的函数。这看起来很邪恶,但似乎没有任何实际缺点(假设它会起作用)。
给定一些 ListItem
类型和希望有一个 ListItem *
值作为 sentinel (also see sentinel node),我们可以简单地定义一个 ListItem
对象来服务它目的:
ListItem SentinelObject;
ListItem * const SentinelValue = &SentinelObject;
如果只在一个翻译单元中使用,也可以static
。
命名对象可以通过使用复合文字来消除:
ListItem * const SentinelValue = & (ListItem) {0};
(如果 0
不是 ListItem
的第一个成员的合适初始化器,则可能需要调整初始化器。)
或者,可以通过将未使用的 ListItem
对象与其他对象重叠来避免浪费 space:
union { SomeUsefulType SomeUsefulThing; ListItem SentinelObject; } MyUnion;
ListItem * const SentinelValue = &MyUnion.SentinelObject;
虽然这为 SomeUsefulThing
和 SentinelObject
提供了相同的地址,但鉴于它们的类型不同,这不太可能成为问题。
链表末尾的尾指针为空(0)似乎很常见。
如果我想要两个可能不同的“尾巴”怎么办?
我的用例是一个支持二进制补码的大整数表示:我想要一个尾巴对应于“这个数字的其余部分是零”和“这个数字的其余部分是一个”,我可以告诉仅通过执行指针相等将它们分开。
看起来这应该很常见,可以有标准的做法,但很难想出到底要搜索什么。我们只得到一个“禁止的”指针值似乎有点武断(当意外取消引用时会产生 useful-ish 错误)。
选项似乎包括:
- 使用一些任意的第二个值(例如 1 或 0xdeadbeef)。这似乎是邪恶的。一方面,我想它需要对齐?此外,如果 malloc 碰巧在同一地址分配一个真正的链表单元格,我也会有一些模糊的错误。是否有一些内存区域 malloc 保证不使用?
- 使用虚拟 non-zero 大小调用 malloc。这似乎更明智,但理想情况下我会将指针值设置为 const,而不需要初始化。
- 获取任意地址,例如文件中定义的函数。这看起来很邪恶,但似乎没有任何实际缺点(假设它会起作用)。
给定一些 ListItem
类型和希望有一个 ListItem *
值作为 sentinel (also see sentinel node),我们可以简单地定义一个 ListItem
对象来服务它目的:
ListItem SentinelObject;
ListItem * const SentinelValue = &SentinelObject;
如果只在一个翻译单元中使用,也可以static
。
命名对象可以通过使用复合文字来消除:
ListItem * const SentinelValue = & (ListItem) {0};
(如果 0
不是 ListItem
的第一个成员的合适初始化器,则可能需要调整初始化器。)
或者,可以通过将未使用的 ListItem
对象与其他对象重叠来避免浪费 space:
union { SomeUsefulType SomeUsefulThing; ListItem SentinelObject; } MyUnion;
ListItem * const SentinelValue = &MyUnion.SentinelObject;
虽然这为 SomeUsefulThing
和 SentinelObject
提供了相同的地址,但鉴于它们的类型不同,这不太可能成为问题。