Windows x64位,5GB RAM。我的二进制文件是64位版本,使用版本编译器构建 - “Microsoft(R)C / C ++优化编译器版本14.00.50727.762 for x64”
Microsoft建议设置以下注册表项以测试64位应用程序,并在我的框中设置相同。如果我没有设置以下注册表,则不会发生此问题,因为程序位于低地址。讨论中提到了相同的注册表项 - As a programmer, what do I need to worry about when moving to 64-bit windows?
要强制分配在较低地址之前从较高地址分配以进行测试,请在调用VirtualAlloc时指定MEM_TOP_DOWN或将以下注册表值设置为0x100000:
HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ Memory Management \ AllocationPreference
char *alloc_str()
{
char *temp;
temp = (char *) malloc(60);
/* copy some data to temp */
return temp;
}
main()
{
char *str;
str = (char *)alloc_str();
}
malloc
返回存储在0x000007fffe999b40
中的地址temp
,但当指针返回main()
时,str
只获得后半部分0xfffffffffe999b40
1}}我无法访问该位置的数据。
答案 0 :(得分:6)
关于风格的两点,这有助于诊断这类问题。在使用malloc
时,我认为它是作为C程序编译的。在这种情况下,不要在没有必要时进行类型转换。过多的类型转换可能会抑制警告,告诉您没有正确声明您的功能。如果没有原型并且函数定义在另一个模块中,则调用str = (char *)alloc_str();
将禁止在没有声明的情况下使用该函数的警告,并且将使用C的默认声明,即所有参数和返回值将是被视为int
。
与malloc
相同,如果您忘记了正确的包含,您的类型转换将禁止警告,编译器将假定该函数返回int
。这可能已经是截断的原因。
另一点,在C中,空参数列表声明为(void)
而不是()
,其具有另一含义(未指定的参数)。
这些是C和C ++之间不同的两点。
答案 1 :(得分:3)
您引用的注册表设置选择自上而下的内存分配。您声明此设置将“将程序置于高地址空间”。它不会那样做。这样做是迫使Windows内存管理器从地址空间的顶部分配内存。
除了在64位Windows下运行之外,我还没有看到PAE在哪里发挥作用。这将是在32位平台上使用的东西。
我猜你正在编译一个32位应用程序,所以你的指针不可避免地是32位宽。但由于缺乏信息,这只是猜测。
简而言之,你的问题是无法回答的,因为你没有告诉我们你在做什么。
答案 2 :(得分:2)
stdlib.h
包含在我的C文件中,因此malloc返回的指针是32位。我遇到的问题是生产代码与示例代码略有不同。
tristopia,你的解释绝对正确。我遇到了同样的问题。
在我的生产C文件中,我遇到了如下问题
<强>交流转换器强>
call_test1()
{
char* temp;
temp = (char *)test1();
}
<强> b.c 强>
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
当str
返回test1()
时,指针包含64位地址(我使用“r rx”分析了rx注册表(存储函数的返回值)在windbg中)但是当它被分配给temp
,它被截断为32位地址。)
问题是由于
test1()
的签名修改后的来源
<强>交流转换器强>
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
<强> b.c 强>
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
我通过反复试验获得了解决方案,但是tristopia解释了原因。
要强制分配在较低地址之前从较高地址分配以进行测试,请在调用MEM_TOP_DOWN
时指定VirtualAlloc
或将以下注册表值设置为0x100000
:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference
答案 3 :(得分:1)
我不得不问你是否正在使用正确的编译器设置并链接到正确的C运行时库。