malloc()返回我无法访问的地址 我有一个C++程序,它调用由Flex/Bys.

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

当我以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 )
{
   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个字节(由于一个我无法更改的库函数…),我只能想象你用这个答案为我节省了多少小时。谢谢人质布莱恩和笑脸(莫拉莱斯):非常好的回答这肯定是我遇到的问题——在我挣扎了几乎一整天之后。非常感谢你!