C++ 64位体系结构-从函数返回时字符指针被截断 环境:
Windows x64位,带5GB RAM。我的二进制文件是64位的,编译版本为“Microsoft(R)C/C++优化编译器版本14.00.50727.762 for x64” 环境设置: Microsoft建议设置下面的注册表项来测试64位应用程序,我已经在我的框中设置了相同的注册表项。如果我不设置下面的注册表,问题就不会发生,因为程序位于较低的地址。讨论中提到了相同的注册表项- 要强制分配从较高地址分配到较低地址,以便进行测试,请在调用VirtualAlloc时指定MEM_TOP_DOWN,或将以下注册表值设置为0x100000: HKEY\U LOCAL\U MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference 示例代码: 分析:C++ 64位体系结构-从函数返回时字符指针被截断 环境:,c++,c,windows,64-bit,C++,C,Windows,64 Bit,Windows x64位,带5GB RAM。我的二进制文件是64位的,编译版本为“Microsoft(R)C/C++优化编译器版本14.00.50727.762 for x64” 环境设置: Microsoft建议设置下面的注册表项来测试64位应用程序,我已经在我的框中设置了相同的注册表项。如果我不设置下面的注册表,问题就不会发生,因为程序位于较低的地址。讨论中提到了相同的注册表项- 要强制分配从较高地址分配到较低地址,以便进行测试,请在调用VirtualAlloc时指定MEM_TOP_DOWN
malloc
返回存储在temp
中的地址0x000007fffe999b40
,但当指针返回到main()
时,str
仅获取下半部分-0xFFFFFFFE999B40
,我无法访问该位置的数据。您参考的注册表设置选择自上而下的内存分配。您声明此设置将“将程序置于高地址空间”。它不会那样做的。这将强制Windows内存管理器从地址空间的顶部分配内存
更重要的是,由于您在64位Windows下运行,我无法看到PAE在何处发挥作用。这将在32位平台上使用
我猜您正在编译一个32位的应用程序,因此不可避免地您的指针是32位宽的。但由于缺乏信息,这只是一个猜测
简而言之,您的问题无法回答,因为您还没有告诉我们您在做什么。我必须询问您是否使用了正确的编译器设置并针对正确的C运行时库进行了链接。关于样式的两点,这有助于诊断此类问题。当您使用malloc时,我假设它被编译为一个C程序。在这种情况下,不要在不必要时进行类型转换。过多的类型转换可能会抑制告诉您没有正确声明函数的警告。如果没有原型并且函数定义在另一个模块中,那么调用
str=(char*)alloc_str()
将取消该函数在未声明的情况下使用的警告,并将使用默认的C声明,即所有参数和返回值将被视为int
。
与malloc
相同,如果您忘记了正确的include,您的类型转换将抑制警告,编译器将假定函数返回int
。这可能已经是截断的原因。
另一点,在C语言中,一个空参数列表是用(void)
声明的,而不是()
,它有另一种含义(未指定的参数)。
这是C和C++的2个不同点。 < P >戴维,谢谢你的时间和建议。示例程序无法运行,因为我的C文件中没有包含
stdlib.h
,因此malloc返回的指针是32位的。我面临的问题是生产代码与示例代码有点不同
三体,你的解释绝对正确。我也面临同样的问题
在我的生产C文件中,我面临的问题如下
a.c
call_test1()
{
char* temp;
temp = (char *)test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
b.c
call_test1()
{
char* temp;
temp = (char *)test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
当test1()
返回str
时,指针包含64位地址(我使用“r rx”分析了windbg中的rx注册表(存储函数返回值),但当它被分配给temp
时,它被截断为32位地址)
这个问题是由于
test1()
的签名call_test1()
{
char* temp;
temp = (char *)test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
b.c
call_test1()
{
char* temp;
temp = (char *)test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
char * test1();
call_test1()
{
char* temp;
temp = test1();
}
include stdlib.h
char* test1()
{
char *str;
test = (char *)malloc(60);
/* copy some data to test*/
return str;
}
我通过反复试验得到了解决方案,但三体素解释了原因
64位注释
VirtualAlloc
时指定MEM\u TOP\u DOWN
,或将以下注册表值设置为0x100000
:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\AllocationPreference
我想你需要说出你实际上在做什么。你提到PAE。你能详细说明一下吗?你函数的返回类型是什么?返回值分配给哪一个变量?您可能会遇到这样的情况:指针中间存储的是某个32位类型的存储。这样的转换会剪切其他32位。请粘贴整个函数。如果它太大,那么把它简化成一个合理的复制。你所说的“被截断”是什么意思?你的程序的
sizeof(char*)
是什么?