如果我有一个存储在变量中的内存位置的地址,即uint64_t64位系统上的8字节指针,我可以使用存储在其中的值uint64_t来创建一个指向它所拥有的内存位置的新指针吗?
struct Node { .. };
Node* node = new Node(5);
uint64_t addr = (uint64_t)static_cast<void*>(&node); // 8 byte pointer
Run Code Online (Sandbox Code Playgroud)
例如,节点的地址是0x7fff76bb4880,addr存储140735185373312(dec表示),我想要一个新的指针Node* new_ptr = (Node*)0x7fff76bb4880.
我意识到这将是特定于平台的.
该标准保证指针可以转换为"足够大"的整数类型并再次返回,从而产生相同的指针值.具体来说,C++ 11 5.2.10重新解释cast [expr.reinterpret.cast]/4:
指针可以显式转换为足以容纳它的任何整数类型.映射函数是实现定义的.
和5:
可以将整数类型或枚举类型的值显式转换为指针.转换为足够大小的整数(如果实现上存在任何此类)并返回相同指针类型的指针将具有其原始值; 指针和整数之间的映射在其他方面是实现定义的.
类型intptr_t和uintptr_tfrom <cstdint>- 如果支持 - 保证足够大以存储任何对象指针类型.通常使用它们 - 即使您知道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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4085 次 |
| 最近记录: |