恢复位域截断地址

Restoring bitfield truncated addresses

我想通过将指针地址截断 1 个字节来节省一些 space。我的指针保证是 16 字节内存对齐的。因此,我可以保证那4个底部位可以被截断。

typedef struct node_t {
   uintptr_t prev : 29;
   uintptr_t next : 29;
} node;

我正在努力恢复那些最底部的字节。向左移动 4 位以尝试恢复最低位中的零只会擦除最前面字节中的数据。

node->next = ((uintptr_t) ptr_addrs >> 4); // successfully stores truncated pointer ex: 0x1024ff010
printf("%p\n", node->next); // prints '0x1024ff01'

如何将位域转换回其原始值(基本上是向该位域附加一个零)?

首先,如果指针是 32 位,删除 4 位会留下 28 位,而不是 29 位。因此声明 29 位的位域似乎是错误的。没有平台使用 33 位作为指针。 29 位肯定足以存储 28 位,但它太大了,无法存储任何 space——您的结构的总 space 要求至少为 58 位,这需要八个八位字节,因为七个字节只能容纳 56 位。

其次,为您的结构使用“完整字段”需要 16 个字节这一事实表明 uintptr_t 是八个字节,因此您平台的指针是八个字节,64 位。从中删除四位,剩下 60 位,而不是 28 位或 29 位。

要回答您的问题“如何将位域转换回其原始值”,只需向左移动四位并转换回原始指针类型。

(有时使用 64 位指针的系统不会使用所有这些位;实际地址 space 可能是 44 位或其他数字,在这种情况下您可以保存 space通过仅存储使用过的位。但是,这种指针压缩非常耗时,并且根据当今的经济学只能节省少量的 space。除非您用包含大部分指针的结构溢出主内存,否则它是不太可能值得。每个指针节省的 space 量乘以指针的数量是否会将您的内存使用量减少到性能下降的阈值以下?)