标记/编码指针

我需要一种方法来将指针标记为集合x的一部分或集合y的一部分(即:标记只有2个’状态’),我就是这意味着可以假定无标记= x和标记= y。

目前我正在寻找使用bitwise xor来做到这一点:

ptr ^ magic = encoded_ptr encoded_ptr ^ magic = ptr 

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

更新

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

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

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

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

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

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

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

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

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

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

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

干杯,

-stan