标记/编码指针

时间:2011-01-03 16:01:52

标签: c++ c bit-manipulation

我需要一种方法将指针标记为集合x的一部分或集合y的一部分(即:标记只有2个'状态'),我就是这意味着可以假设未标记= x并标记=收率

目前我正在使用bitwise xor来执行此操作:

ptr ^ magic = encoded_ptr
encoded_ptr ^ magic = ptr

但是我很难知道如何确定指针是否在第一时间被标记。 我用它来标记链表中的哪些池节点来自哪里,这样当它们脱钩时,它们可以回到正确的perants。

更新

为了向所有那些建议将标志存储在额外数据成员中的人说清楚,我只限于sizeof(void*),所以我不能添加新成员,否则我会有。此外,池不是连续的,它们由许多页面组成,跟踪范围会增加太多开销(我正在使用快速和简单的解决方案,如果有人可以调用它)。 / p>

5 个答案:

答案 0 :(得分:15)

大多数解决方案都是特定于平台的。这里有一些:

1)mallocnew返回的指针将对齐(4,8,16,32字节,您可以将其命名)。因此,在大多数体系结构中,地址的几个LSB位始终为0。

2)以Win32为特定方式:除非你的程序使用3GB开关,否则所有用户模式指针的值都小于0x80000000,因此最高位可以用作标志。作为奖励,当标记指针被解除引用而未被修复时,它也会崩溃。

答案 1 :(得分:8)

没有安全便携的方式让这类事情发挥作用。您可能能够找到一些特定于系统的位,这些位始终是已知值(例如,最重要的n位),但这是一个非常脆弱且危险的依赖。您无法判断指针是否“已标记”,除非指针中的某些位首先具有已知值。

更好的方法是在指针指向的结构中存储标识符。

答案 2 :(得分:2)

当然,如果你只有两个池,当你为每个池分配内存时,你知道可能的地址范围 - 那么为什么不用简单的指针算法检查你的指针是否出现在一个或另一个地址范围内?

答案 3 :(得分:0)

如果性能不是一个大问题,可以使用两个std :: set。

如果快速获取此信息很重要,并且只使用2字节对齐指针是可以接受的,则可以使用最低位来存储此信息。但是,“破解”指针似乎很容易出错......

答案 4 :(得分:0)

你可能有ptr1 ^ magic = ptr2,其中集合X中的ptr1和集合Y中的ptr2(除非你另有证明)。因为(我猜)你没有控制你给出的指针地址,你的技术似乎是不够的。

Vinay解决方案的另一种方法是将标签存储为预分配缓冲区的位(如果列表的大小有限,则特别容易,因为您不必增大或缩小缓冲区)。这是一个非常紧凑和高效的解决方案,不需要修改指向的数据结构。

干杯,

-stan