存储在uint64_t中的内存位置指针

3
如果我有一个存储在变量中的内存地址,比如64位系统上8字节指针的uint64_t,那么我能否使用存储在uint64_t中的值来创建一个新指针,指向它所保存的内存位置?
struct Node { .. };
Node* node = new Node(5);
uint64_t addr = (uint64_t)static_cast<void*>(&node); // 8 byte pointer

例如节点的地址为0x7fff76bb4880addr存储140735185373312(十进制表示),我想要一个新的指针Node* new_ptr = (Node*)0x7fff76bb4880
我意识到这将是特定于平台的。
1个回答

11

标准保证指针可以转换为“足够大”的整数类型,然后再转回来得到相同的指针值。具体来说,C++11 5.2.10 Reinterpret cast [expr.reinterpret.cast]/4:

 

指针可以显式地转换为足以容纳它的任何整数类型。映射函数是实现定义的。

和 5:

 

整数类型或枚举类型的值可以被明确地转换为指针。将指针转换为足够大的整数(如果在实现中存在这样的整数)并再次转换回相同的指针类型,则其原始值将保持不变;指针和整数之间的映射是实现定义的。

类型 <cstdint> 中的 intptr_tuintptr_t - 如果受支持 - 被保证足够大,可以存储任何对象指针类型。通常使用它们 - 即使您知道在您的平台上 uint64_t 是指针的大小 - 因为它们清楚地表明您打算在指针和整数之间进行转换。

我将留给读者作为练习证明 C 式转换等效于执行 reinterpret_cast

TLDR: 标准保证此程序永远不会失败断言:

auto pointer_as_int = reinterpret_cast<uintptr_t>(&foo);
auto int_as_pointer = reinterpret_cast<decltype(&foo)>(pointer_as_int);
assert(&foo == int_as_pointer);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接