链表末尾的尾指针为空 (0) 似乎很常见。
如果我想要有两个可能不同的“尾巴”怎么办?
我的用例是一个支持二进制补码的大整数表示:我想要一个对应于“这个数字的其余部分是零”和“这个数字的其余部分是一”的尾部,我可以通过执行来区分它们指针相等。
看起来这应该很常见,可以有标准实践,但很难确切地想到要搜索什么。我们只得到一个“禁止”的指针值(当意外取消引用时会给出一个有用的错误),这似乎有点武断。
选项似乎包括:
- 使用一些任意的第二个值(例如 1 或 0xdeadbeef)。这看起来很邪恶。一方面,我想它需要对齐?另外,如果 malloc 碰巧在同一地址分配了一个真实的链表单元,我将会遇到一些模糊的错误。是否有某些区域的内存 malloc 保证不使用?
- 使用虚拟非零大小调用 malloc。这似乎更明智,但理想情况下我希望指针值是 const,而不是需要初始化。
- 获取任意内容的地址,例如文件中定义的函数。这看起来很邪恶,但似乎没有任何实际的缺点(假设它会起作用)。
It seems common to have the tail pointer at the end of a linked list be null (0).
What if I want to have two possible different "tails"?
My use case is a big integer representation that supports two's complement: I want to have a tail corresponding to "the rest of this number is zeros" and "the rest of this number is ones", where I can tell them apart just by performing a pointer equality.
It seems like this should be common enough to have standard practice, but it's hard to think of exactly what to search for. It seems somewhat arbitrary that we only get one "forbidden" pointer value (that will give a useful-ish error when accidentally dereferenced).
Options seem to include:
- Use some arbitrary second value (like 1, or 0xdeadbeef). This seems evil. For one thing, I guess it needs to be aligned? Also, I will have obscure bugs if malloc happens to allocate a real linked list cell at the same address. Is there some region of memory malloc is guaranteed not to use?
- Call malloc with a dummy non-zero size. This seems more sensible, but ideally I would have the pointer value be const, rather than requiring initialisation.
- Take the address of something arbitrary, like a function defined in the file. This seems very evil, but does seem to lack any practical disadvantages (assuming it would work).
发布评论
评论(1)
给定一些
listItem
类型,并且希望拥有listItem *
值,该值用作 sentinel (另请参见 listItem 对象来实现此目的:如果仅在一个翻译单元中使用它们,也可以将其进行
static
。可以使用复合文字来消除命名的对象:(
不是
listiTem
的第一个成员的合适启动器,则可能需要调整。如果
0
可以通过将未使用的listItem
对象与其他对象重叠来避免空间:虽然给出
someusefulthing
andsentinelobject
是相同的地址,但不可能鉴于它们具有不同的类型,成为一个问题。Given some
ListItem
type and a desired to have aListItem *
value that serves as a sentinel (also see sentinel node), we can simply define aListItem
object to serve that purpose:This could also be made
static
if they will be used only in one translation unit.The named object could be eliminated by using a compound literal:
(The initializer may need adjustment if
0
is not a suitable initailizer for the first member ofListItem
.)Alternately, wasting space could be avoided by overlapping the unused
ListItem
object with some other object:While this gives
SomeUsefulThing
andSentinelObject
the same address, that is unlikely to be a problem given they have different types.