为了测试是否long
或long long
实际上足以容纳一个指针,只需添加一个静态断言(C++ 11本已建成,但你也可以自己做一个有#define my_static_assert(x) ((void)sizeof(char[1 - 2*!(x)]))
)和依赖的功能在这个特别的东西添加
/* function passes a pointer through a long */
static_assert(sizeof(long) >= sizeof(uintptr_t));
或
/* function passes a pointer through a long long */
static_assert(sizeof(long long) >= sizeof(uintptr_t));
这将需要的任何截断问题护理。但是,如果你调用的库对指针值做了一些疯狂的事情,比如掩盖它的某些部分或类似的东西,它并不会帮助你。或者,如果库在内部将指针缩短为针对指针的类型太短。这真的只能经验性地被测试给它高地址。
有关地址空间的一些注意事项:x86_64具有标准化地址的概念,这意味着高位全部相同,并且在物理可寻址区域的大小内复制实际地址的最高位。这是为了确保未来物理地址空间的扩展,一般来说是个好主意。通常地址空间的分区是这样的,即上半部分(0xF ...............)属于内核,下半部分(0x7 ........) .......)是用户空间(对于32位也是如此,只有一半位)。
分配虚拟地址空间所需区域的指针是可能的。在POSIX系统中,mmap
系统调用允许您指定一个起始地址作为第一个参数。在Windows中有VirtualAlloc
起始地址必须页面对齐,但这很容易:只要让地址的低20位为0,即使是巨大的页面,它也会如此。堆栈位于用户地址空间的上端(0x7F ..............),然后通常是动态加载的库。程序文本开始waaay下来,随后堆积长大。他们之间有一个很大的空白,可以用mmap
或VirtualAlloc
来填充。所以对于你的测试,我会随机在中间的某个地方随机移动一个测试地址,即0x777777 .... 000000(用随机数填充点)。在一个最小的测试程序中,地址范围应该是未使用的并且试图映射一个内存区域应该可以工作。
这不是C++语言标准的一部分,但你可以调整make文件。知道你的动机是什么可能是有用的。如果只是为了验证您的应用程序可以处理高地址,那么在高地址上实际分配变量时模拟该场景可能就足够了。 –
我假设你分配了4GB内存后,任何后续分配将在更高的地址。您可能必须向每个内存页面写入一个字节以标记分配的物理内存。 –
@ PeterA.Schneider:我很确定OP会在事后得到一堆其他问题。为了测试系统的目的,我不太确定这种方法是多么有用。 –