I have a C++ program that calls some C routines that are generated by Flex / Bison.
When I target a Windows 8.1 64-bit platform, I hit the following exception at runtime:
Unhandled exception at 0x0007FFFA70F2C39 (libapp.dll) in application.exe: 0xC0000005:
Access violation writing location 0x000000005A818118.
I traced this exception to the following piece of code:
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
}
For reference, elsewhere in the code (also generated by Flex / Bison), we have:
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 );
}
I traced back to the malloc
call and observed that malloc
itself is returning the address 0x000000005A818118
. I also checked errno
, but it is not set after the call to malloc
.
My question is: why does malloc
give me an address that I don't have access to, and how can I make it give me a correct address?
Note: I only observe this behavior in Windows 8.1 64-bit. It passes with other 32-bit Windows variants, as well as Windows 7 32-bit.
Compilation information: I am compiling this on a 64-bit Windows 8.1 machine using Visual Studio 2012.
If it helps, here is the disassembled code:
// 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
Thanks!
malloc
either returns00000000--------
orFFFFFFFF--------
for the address of the "allocated" space. – Disjunctureyy_flex_alloc
is defined include stdlib? If not, it's likely that it treats the return value frommalloc
as an int and the cast hides it. – Didymousyy_flex_alloc()
is defined indeed contains#include <stdlib.h>
. This file is generated automatically by Flex. – Disjuncturefree
in the C++ part of your program for memory that was allocated bymalloc
in the C part, and vice versa – Ferdyreturn (void *) malloc( size );
should bereturn malloc(size);
. Make sure that the file actually does#include <stdlib.h>
. Also make sure that you do not try to compile C files with the C++ compiler. – Ferdy