malloc()返回我无法访问的地址 我有一个C++程序,它调用由Flex/Bys.
当我以Windows 8.1 64位平台为目标时,我在运行时遇到以下异常:malloc()返回我无法访问的地址 我有一个C++程序,它调用由Flex/Bys.,c++,c,visual-studio-2010,malloc,flex-lexer,C++,C,Visual Studio 2010,Malloc,Flex Lexer,当我以Windows 8.1 64位平台为目标时,我在运行时遇到以下异常: Unhandled exception at 0x0007FFFA70F2C39 (libapp.dll) in application.exe: 0xC0000005: Access violation writing location 0x000000005A818118. 我将此异常追溯到以下代码段: YY_BUFFER_STATE yy_create_buffer( FILE *file, int size
Unhandled exception at 0x0007FFFA70F2C39 (libapp.dll) in application.exe: 0xC0000005:
Access violation writing location 0x000000005A818118.
我将此异常追溯到以下代码段:
YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
{
YY_BUFFER_STATE b;
b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_buf_size = size; // This access is what throws the exception
}
作为参考,在代码的其他地方(也由Flex/Bison生成),我们有:
typedef struct yy_buffer_state *YY_BUFFER_STATE;
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf;
char *yy_buf_pos;
yy_size_t yy_buf_size;
// ... other fields omitted,
// total struct size is 56 bytes
}
static void *yy_flex_alloc( yy_size_t size )
{
return (void *) malloc( size );
}
我追溯到malloc
调用,发现malloc
本身正在返回地址0x000000005A818118
。我还检查了errno
,但在调用malloc
之后没有设置它
我的问题是:malloc
为什么给我一个我无法访问的地址,我如何才能让它给我一个正确的地址
注意:我只在Windows 8.1 64位中观察到这种行为。它与其他32位Windows变体以及32位Windows 7一起通过
编译信息:我正在使用Visual Studio 2012在64位Windows 8.1计算机上编译此文件
如果有帮助,以下是反汇编代码:
// b = (YY_BUFFER_STATE) yy_flex_alloc( ... )
0007FFFA75E2C12 call yy_flex_alloc (07FFFA75E3070h)
0007FFFA75E2C17 mov qword ptr [b],rax
// if ( ! b ) YY_FATAL_ERROR( ... )
0007FFFA75E2C1C cmp qword ptr [b],0
0007FFFA75E2C22 jne yy_create_buffer+30h (07FFFA75E2C30h)
0007FFFA75E2C24 lea rcx,[yy_chk+58h (07FFFA7646A28h)]
0007FFFA75E2C2B call yy_fatal_error (07FFFA75E3770h)
// b->yy_buf_size = size
0007FFFA75E2C30 mov rax,qword ptr [b]
0007FFFA75E2C35 mov ecx,dword ptr [size]
0007FFFA75E2C39 mov dword ptr [rax+18h],ecx
谢谢 在正常情况下,malloc()将返回指向有效、可访问内存的指针,否则返回NULL。因此,您的症状表明malloc()以未指定的方式运行。我怀疑,在之前的某个时候,您的程序在其有效内存之外编写,从而破坏了malloc()内部使用的数据结构 使用运行时内存分析工具检查流程应该有助于确定问题的根源。[有关Windows内存分析工具的建议,请参阅本文:真正的答案是: 在Visual Studio中编译flex生成的
.c
源代码时,它不包括stdlib.h
(其中malloc定义为返回void*),Visual Studio采用一些自己的定义,其中malloc返回int。(我认为这是为了某种兼容性)
Visual studio打印:
'警告C4013:'malloc'未定义;假设extern返回int'
sizeof(int)==4,但x64系统上指针中的值通常超过4字节
所以你的指针就切到了低4字节
这个问题似乎只出现在visual studio的.c
文件中的x64
bits中
因此,解决方案将是-只需自己包含stdlib.h,或者定义一些宏,这将导致flex生成的源代码中包含
stdlib.h
,malloc
返回00000000------
或FFFFFFFF------
作为“已分配”的地址最有可能的是,代码中其他一些看似不相关的部分破坏了堆(例如,通过溢出堆分配的缓冲区)。您正在查看的代码部分是无辜的受害者。您的程序正在经历堆损坏的情况。你可以参考这篇文章的帖子:定义了yy_flex_alloc
的文件是否包括stdlib?如果不是,则很可能它将来自malloc
的返回值视为int,而强制转换将其隐藏。@Art:定义yy_flex_alloc()
的文件确实包含\include
。此文件由Flex自动生成。谢谢,这是一个很好的建议。我会尽快调查它,我可以安装一个Windows 8兼容的泄漏检测器。。。不过,我确实在这个应用程序的Linux版本上运行了Valgrind,而且似乎没有任何可疑之处。当这部分代码运行时,我只丢失了4个字节(由于一个我无法更改的库函数…),我只能想象你用这个答案为我节省了多少小时。谢谢人质布莱恩和笑脸(莫拉莱斯):非常好的回答这肯定是我遇到的问题——在我挣扎了几乎一整天之后。非常感谢你!