将无符号整数存储在指针中

Posted

技术标签:

【中文标题】将无符号整数存储在指针中【英文标题】:Storing unsigned integer in a pointer 【发布时间】:2016-12-13 21:40:47 【问题描述】:

我正在构建一个八叉树数据结构,为了为最终节点节省内存,我希望将值直接存储在指针中,而不必创建一个可容纳 8 个子节点的对象。

我的数据类型是 uint32_t,这意味着指针有足够的位来保存它在 x86 或 amd64 上。

那么如何将无符号 32 位整数存储在 x86 或 amd64 指针中?

伪代码:

uint32_t i = 123;
Octree* ptr = i;
uint32_t ii = ptr;
std::cout << ii << std::endl; //Prints 123

这怎么可能?

【问题讨论】:

uint32_t i = 123; Octtree* ptr = reinterpret_cast(i); uint32_t ii = reinterpret_cast(ptr); @FamZ:虽然在 x86 上应该可以工作,但在技术上它是非法的,一些奇怪的平台会导致崩溃(甚至只是 引用 i> 指向无效指针会在这些 CPU 上触发硬件异常)。 【参考方案1】:

不允许将无符号整数直接存储在 in 指针中,但您可以:

反过来:您可以将指针存储在无符号整数中;具体来说,uintptr_t 被标准明确保证足够大,让指针在往返过程中存活;

使用union:

union NodePtr 
    Octree *child;
    uint32_t value;

这里childvalue 共享相同的内存位置,并且您只能从上次写入的位置读取;当你在终端节点时使用value,否则使用child

【讨论】:

使用联合有什么开销吗?上面的联合会占用与原始指针相同的空间吗? @KaareZ: unions 在任何体面的实现上几乎都是免费的——它们只是用来告诉编译器您将要访问具有多种类型的内存,因此适用最严格的对齐要求;联合体的大小“足以存储其最大的数据成员”(实际上,它通常与其最大的成员一样大)。 好的,先生,这是一个非常好的解决方案。谢谢。【参考方案2】:

好吧,您可以将 int 存储为带有强制类型转换的指针:

uint32_t i = 123;
Octree* ptr = reinterpret_cast<Octree*>(i);
uint32_t ii = reinterpret_cast<uint32_t>(ptr);
std::cout << ii << std::endl; //Prints 123

但是如果你这样做,我看不出你是如何检测到给定的八叉树*实际存储数据而不是指向另一个八叉树的指针

【讨论】:

我会为此设置一个布尔标志。 如上所述,虽然这将适用于 x86 和其他常见架构,但从技术上讲它是不可移植的(允许指针具有陷阱表示)。

以上是关于将无符号整数存储在指针中的主要内容,如果未能解决你的问题,请参考以下文章

如何以优雅有效的方式将无符号/有符号整数/长整数转换为 C 字符串?

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

将无符号整数输入属性传递给顶点着色器

使用啥 ffmpeg 命令将无符号整数列表转换为音频文件?

任何可用于 C 中无符号字符指针行为的文档? [复制]

如何从 Python 将无符号值发送到 dBus