C++ 对于64位测试(各种平台),是否有编译器标志让malloc返回高于4G限制的指针?
我需要测试从32位移植到64位的代码,其中指针被转换为整数句柄,并且我必须确保在64位平台上使用正确大小的类型 各种编译器是否有任何标志,甚至运行时是否有标志可确保C++ 对于64位测试(各种平台),是否有编译器标志让malloc返回高于4G限制的指针?,c++,testing,64-bit,malloc,C++,Testing,64 Bit,Malloc,我需要测试从32位移植到64位的代码,其中指针被转换为整数句柄,并且我必须确保在64位平台上使用正确大小的类型 各种编译器是否有任何标志,甚至运行时是否有标志可确保malloc返回大于32位限制的指针值 我感兴趣的平台: Windows XP 64和其他64位Windows上的Visual Studio 2008 使用xLC的AIX 64位gcc 使用aCC的64位HP/UX 分配4GB的示例应用程序 因此,多亏R Samuel Klatchko的回答,我能够实现一个简单的测试应用程序,它将尝
malloc
返回大于32位限制的指针值
我感兴趣的平台:
分配4GB的示例应用程序 因此,多亏R Samuel Klatchko的回答,我能够实现一个简单的测试应用程序,它将尝试在第一个4GB地址空间中分配页面。希望这对其他人和其他用户有用,因此用户可以告诉我它的便携性/有效性
#include <stdlib.h>
#include <stdio.h>
#define UINT_32_MAX 0xFFFFFFFF
#ifdef WIN32
typedef unsigned __int64 Tuint64;
#include <windows.h>
#else
typedef unsigned long long Tuint64;
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#endif
static void* Allocate(void* pSuggested, unsigned int PageSize)
{
#ifdef WIN32
void* pAllocated = ::VirtualAlloc(pSuggested, PageSize, MEM_RESERVE ,PAGE_NOACCESS);
if (pAllocated)
{
return pAllocated;
}
return (void*)-1;
#else
void* pAllocated = ::mmap(pSuggested,
PageSize,
PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
-1,
0);
if (pAllocated == MAP_FAILED)
{
pAllocated = (void*)-1;
}
return pAllocated;
#endif
}
static void Deallocate(void* pRegion, unsigned int PageSize)
{
#ifdef WIN32
::VirtualFree(pRegion,0,MEM_RELEASE);
#else
::munmap(pRegion,PageSize);
#endif
}
static void Gobble32bitAddressSpace()
{
#ifdef WIN32
SYSTEM_INFO SysInfo;
::GetSystemInfo(&SysInfo);
unsigned int PageSize = SysInfo.dwAllocationGranularity;
#else
unsigned int PageSize = ::sysconf(_SC_PAGE_SIZE);
#endif
unsigned int AllocatedPages = 0;
unsigned int SkippedPages = 0;
void *pStart = 0;
while( ((Tuint64)pStart) < UINT_32_MAX)
{
void* pAllocated = Allocate(pStart, PageSize);
if (pAllocated != (void*)-1)
{
if (pAllocated == pStart)
{
//Allocated at expected location
AllocatedPages++;
}
else
{
//Allocated at a different location
//unallocate and consider this page unreserved
SkippedPages++;
Deallocate(pAllocated,PageSize);
}
}
else
{
//could not allocate at all
SkippedPages++;
}
pStart = (char*)pStart + PageSize;
}
printf("PageSize : %u\n",PageSize);
printf("Allocated Pages : %u (%u bytes)\n",AllocatedPages,PageSize*AllocatedPages);
printf("Skipped Pages : %u (%u bytes)\n",SkippedPages,SkippedPages*PageSize);
}
int main()
{
Gobble32bitAddressSpace();
//Try to call malloc now and see if we get an
//address above 4GB
void* pFirstMalloc = ::malloc(1024);
if (((Tuint64)pFirstMalloc) >= UINT_32_MAX)
{
printf("OK\n");
}
else
{
printf("FAIL\n");
}
return 0;
}
#包括
#包括
#定义UINT_32_最大0xFFFFFFFF
#ifdef WIN32
typedef unsigned_uuint64 Tuint64;
#包括
#否则
typedef无符号长Tuint64;
#包括
#包括
#包括
#包括
#恩迪夫
静态void*Allocate(void*pSuggested,unsigned int PageSize)
{
#ifdef WIN32
void*pAllocated=::VirtualAlloc(pSuggested、PageSize、MEM_RESERVE、PAGE_NOACCESS);
如果(无效)
{
回归苍白;
}
返回(无效*)-1;
#否则
void*pAllocated=::mmap(pSuggested,
页面大小,
普罗图诺,
MAP|u PRIVATE | MAP|u ANONYMOUS | MAP|u NORESERVE,
-1,
0);
if(pAllocated==MAP_失败)
{
pAllocated=(void*)-1;
}
回归苍白;
#恩迪夫
}
静态void解除分配(void*pRegion,unsigned int PageSize)
{
#ifdef WIN32
::VirtualFree(pRegion、0、MEM_发布);
#否则
::munmap(pRegion,PageSize);
#恩迪夫
}
静态void Gobble32bitAddressSpace()
{
#ifdef WIN32
系统信息系统信息;
::GetSystemInfo(&SysInfo);
unsigned int PageSize=SysInfo.dwAllocationGranularity;
#否则
unsigned int PageSize=::sysconf(_SC_PAGE_SIZE);
#恩迪夫
unsigned int AllocatedPages=0;
unsigned int SkippedPages=0;
void*pStart=0;
而(((Tuint64)pStart)=UINT\U 32\U最大值)
{
printf(“OK\n”);
}
其他的
{
printf(“失败\n”);
}
返回0;
}
我过去使用过的一种技术是在启动时分配足够的内存,以使低于4GB限制的所有地址空间都用完。虽然这种技术确实依赖malloc首先使用地址空间的较低部分,但在我工作的所有平台(Linux、Solaris和Windows)上都是如此
由于Linux是如何使用Overmit的,如果您不触及低于4GB限制的分配空间,就不会使用任何虚拟内存
在Windows上,您可以使用带有MEM_RESERVE标志的VirtualAlloc()来耗尽地址空间,而无需分配任何实际存储。您最好重写代码,以便使用intptr_t类型,因为这正是为了使此类实践更安全。不幸的是,它是在c99头文件中定义的,并且VC++不支持c99。但是,这不会阻止您为该平台创建这样的头 您还可以在发生此类强制转换时添加断言,例如
assert( sizeof(integer_param) == sizeof(void*) ) ;
或者您可以将值转换回原始指针类型,然后比较:
assert( (mytype*)integer_param == original_pointer ) ;
不是编译器开关,而是Windows的启动时开关可以执行您想要的操作。有一个名为“nolomem”的命令,它强制将所有内容加载到大于4GB的地址空间中 如果您使用的是XP,您应该能够在boot.ini中使用/nolomem。请参见OSR上的 对于Vista/Win7,您可以使用NOLOMEM选项。文件是。可以这样做:
bcdedit /set {current} NOLOMEM
不是你特别要求的,而是对于其他可能好奇的人来说,Mac OS X上的gcc似乎默认从4GB以上的区域分配64位程序 下面是一个C程序,用于在任何编译器/操作系统组合上验证这一点:
#include <stdlib.h>
#include <stdio.h>
int main() {
void *p = malloc(1000);
printf("%p\n", p);
return 0;
}
#包括
#包括
int main(){
void*p=malloc(1000);
printf(“%p\n”,p);
返回0;
}
为什么不一开始就分配一次4G呢。只要不写入内存,它就不会从实际物理内存中带走多少,只会占用分页表。你也可以使用一个指向自动(堆栈)变量的指针,它总是远高于4G。所以我尝试了一下……在windows上,我可以建议一个开始指针进行分配,这样我们就可以连续分配地址空间的低端。这在unix上也可行吗?mmap
调用将允许您这样做。使用MAP\u ANON
获取非文件备份内存。