我写了一个简单的C程序转换char成Tokens.事情很好但我无法理解为什么size变量值正在改变.
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;
}
Run Code Online (Sandbox Code Playgroud)
如果code包含"abcde",则输出为:
BEFORE PARSE: 5
AFTER PARSE: 142786584
Run Code Online (Sandbox Code Playgroud)
第二个printf在不同的运行中显示不同的值.
请帮忙 !
PS:我是C菜鸟!
编辑:
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;
}
Run Code Online (Sandbox Code Playgroud)
您有一个典型的缓冲区溢出案例。
char* code;
Run Code Online (Sandbox Code Playgroud)
分配一个指向字符(通常为 8 个字节)的指针,而不是保存文件数据的缓冲区。
与相同
Token *tokens;
Run Code Online (Sandbox Code Playgroud)
当您写入时,tokens您parse会覆盖堆栈的一部分并size用它来覆盖。
为他们分配足够的内存!
char * code = malloc(0x1000);
Token *tokens = malloc(0x100 * sizeof(Token *));
Run Code Online (Sandbox Code Playgroud)
并传递指针,而不是它的地址:
read_file( path, code );
parse( code, size, tokens );
Run Code Online (Sandbox Code Playgroud)
这是更正后的代码:
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;
}
Run Code Online (Sandbox Code Playgroud)