I've written a simple C program to convert char
into Token
s. Things work fine but I'm unable to understand why the size
variable value is changing.
typedef struct _token {
int val;
} Token;
void parse( char* code, int size, Token** tokens ) {
int i = 0;
for (; i < size; i++) {
tokens[i] = malloc(sizeof(Token));
tokens[i]->val = code[i];
}
}
int execute( char *path ) {
char* code;
if ( read_file( path, &code ) != 0 ) {
return -1;
}
int size = strlen(code) - 1;
printf("BEFORE PARSE: %d\n", size); // 1st printf
Token *tokens;
parse( code, size, &tokens );
printf("AFTER PARSE: %d\n", size); // 2nd printf
return 0;
}
if code
contains "abcde"
, the output is:
BEFORE PARSE: 5
AFTER PARSE: 142786584
The second printf
displays different values on different runs.
Please help !
PS: I'm a C noob !
EDIT:
int read_file(char* path, char** code) {
FILE* fp = fopen ( path , "rb" );
if( !fp ) {
return -1;
}
fseek( fp , 0L , SEEK_END);
long lSize = ftell( fp );
rewind( fp );
/* allocate memory for entire content */
*code = calloc( 1, lSize+1 );
if( !*code ) {
fclose( fp );
return -1;
}
/* copy the file into the buffer */
if( 1 != fread( *code , lSize, 1 , fp) ) {
fclose(fp);
return -1;
}
fclose( fp );
return 0;
}
You have a typical case of buffer overflow.
char* code;
Allocates a pointer to character (typically 8 bytes), not a buffer to hold your file data.
Same with
Token *tokens;
When you write to tokens
in parse
you overwrite part of your stack and size
with it.
Allocate enough memory for them!
char * code = malloc(0x1000);
Token *tokens = malloc(0x100 * sizeof(Token *));
And pass the pointer, not it's address:
read_file( path, code );
parse( code, size, tokens );
Here is corrected code:
typedef struct _token {
int val;
} Token;
void parse( char* code, int size, Token* tokens ) {
int i = 0;
for (; i < size; i++) {
// you already have memory now
tokens[i]->val = code[i];
}
}
int execute( char *path ) {
char* code = malloc(0x1000);
if ( read_file( path, code ) != 0 ) {
return -1;
}
int size = strlen(code) - 1;
printf("BEFORE PARSE: %d\n", size); // 1st printf
Token *tokens = calloc(sizeof(Token), 0x100);
parse( code, size, tokens );
printf("AFTER PARSE: %d\n", size); // 2nd printf
return 0;
}
It is because tokens is never initialized. Change it to:
Tokens **tokens = malloc(sizeof(Tokens *) * size);
Don't forget to free the memory when you are done with it:
for (; i < size; i++) {
free(tokens[i]);
}
free(tokens);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With