我正在对一个组件进行测试,我将指针传递给内存中的数据块。
我想把数据包放在一个更高的地址空间,地址宽度超过32位(我在Windows 7 64位上运行)。这样我就可以看出该组件是否容忍指针地址。
我想要测试的组件中有两个功能。一个接收long
,另一个接收缓冲区地址long long
。
foo1(long long ptrBuffer, long size);
foo2(long ptrBuffer, long size);
我正在使用visual studio 2013(C ++)。有没有办法告诉VS将变量放在内存中的哪个位置?
答案 0 :(得分:4)
您可以替换operator new
,但这不会影响全局变量或局部变量(即堆栈)。但是,对于测试用例,您可以传递新对象的地址。然后,从操作系统中获取5 GB。至少1GB将超过4GB,将其用作operator new
的支持池。
Win32方法是使用VirtualAlloc
调用MEM_TOP_DOWN
。
答案 1 :(得分:2)
要测试kota
或long
实际上是否足以容纳指针,只需添加一个静态断言(C ++ 11内置了这个,但你也可以自己制作一个{ {1}})并且在依赖于这个特定事物的函数中添加
long long
或
#define my_static_assert(x) ((void)sizeof(char[1 - 2*!(x)]))
这将解决任何截断问题。但是,如果你正在调用的库正在对指针值做一些疯狂的事情,比如屏蔽它的一些部分或类似的东西,它对你没有帮助。或者,如果库内部将指针截断为对于指针来说太短的类型。真正只能凭经验测试才能为它提供高地址。
关于地址空间的一些注意事项:x86_64具有归一化地址的概念,这意味着高位都是相同的,并且在物理可寻址区域的大小内复制实际地址的最高位。这是为了确保未来物理地址空间的扩展,一般来说是一个好主意。通常分区的地址空间是这样的,上半部分(0xF ...............)属于内核和下半部分(0x7 ........ .......)是用户空间(也是32位的情况,只有一半的位)。
可以从所需的虚拟地址空间区域分配指针。在POSIX系统中,/* function passes a pointer through a long */
static_assert( sizeof(long) >= sizeof(uintptr_t) );
系统调用允许您指定起始地址作为第一个参数。在Windows中有VirtualAlloc
起始地址必须是页面对齐的,但这很容易:只要让地址的低20位为0,即使是大页面也是如此。堆栈位于用户地址空间的上端(0x7F ..............),然后通常是动态加载的库。程序文本开始等待,然后堆成长。在他们之间有一个很大的空白,可以填充/* function passes a pointer through a long long */
static_assert( sizeof(long long) >= sizeof(uintptr_t) );
或mmap
。因此,对于您的测试,我会在中间的某个地方随机地随机移动测试地址,即0x777777 .... 000000(用随机数字填充点)。在一个最小的测试程序中,地址范围应该是未使用的并且试图映射存储区域应该可以工作。
答案 2 :(得分:1)
c ++标准不支持。
顺便说一句,如果你想将指针地址存储为整数,请使用uintptr_t
。
uintptr_t
以将指针地址存储为整数句柄。
答案 3 :(得分:0)
没有C ++方法可以执行此操作,但您可以使用操作系统特定功能来执行此操作。
对于Windows,您可以使用VirtualAlloc()在精确的地址分配(并提交)内存。