c - 将 64 位指针存储在 32 位整数中,前提是最大虚拟内存地址 <= UINT32_MAX(例如,当 RAM 大小 <= 4GB 时)

标签 c pointers 64-bit 32bit-64bit virtual-memory

是否有任何平台(如果有,是哪个?)可以执行以下操作,前提是运行时检查确认没有超过 4GB 的可用虚拟内存(或 RAM)?

// 1) cast pointer to void pointer
// 2) cast void pointer to uint64 type
// 3) set most significant bytes of uint64 type to 0 (might be wrong choice)
// 4) store as uint32 type
uint32_t trimmed_pointer = (uint64_t) (void *) pointer & 0x00000000ffffffff;

并取回原始指针:

same_as_before_t *pointer = (void *) (uint64_t) trimmed_pointer

我意识到这可能是一个可怕的黑客行为,并且完全取决于操作系统的内存管理器如何实现虚拟内存(以及编译器?),所以我问这个纯粹是出于好奇。

最佳答案

为了帮助移植那些假定指针可以安全地存储在 32 位整数类型中的笨拙的旧 32 位程序,Windows 仍然尊重 64 位 PE header 中的 IMAGE_FILE_LARGE_ADDRESS_AWARE 标志。位程序。

如果程序头中未设置该标志,系统将不会为进程分配超过 2GB 的地址。

默认情况下,对于 64 位构建,链接器会设置该标志(即,默认情况下 64 位程序的地址空间不会受到限制)。如果您想指示您的 64 位程序不应获得超过 2GB 的任何地址空间,请在构建程序时将 /largeaddressaware:no 选项传递给链接器。请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/aa384271.aspx了解详情。

请记住,此功能旨在帮助移植无法正确处理指针的程序,而不是让您能够编写此类程序。还要记住一个重要的事实,即虚拟地址与物理地址关系不大(换句话说,即使您的 RAM 小于 4GB,系统仍然可以使用 TB 范围内的虚拟地址)。

关于c - 将 64 位指针存储在 32 位整数中,前提是最大虚拟内存地址 <= UINT32_MAX(例如,当 RAM 大小 <= 4GB 时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17290115/

相关文章:

C++ : Two pointers (supposedly) to the same address. 改变其中一个的内容不会改变另一个的内容

c# - 不安全的 C# 代码会导致 64 位平台上的堆损坏,除非为 x86 平台构建

c++ - 为什么 new/malloc 在 Win x64 上失败,尽管有足够的空闲 RAM?

php - PHP 5.2 和 PHP 5.3 中大整数的按位运算

c - GetProcAddress 为所有函数返回 0

C程序确定没有 'e'或 'E'的char数组中的最大子串

c++ - Glibc 在调用新关键字 C++ 时检测到 malloc() 内存损坏 (0xb6179bb8)

c - 这个程序的输出是什么?

c++ - 为什么引用在 C++ 中不可重新安装

在 C 中从命令行创建数组