我编写了一个简单的C程序,将char
转换为Token
s。事情很好但我无法理解为什么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;
}
如果code
包含"abcde"
,则输出为:
BEFORE PARSE: 5
AFTER PARSE: 142786584
第二个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;
}
答案 0 :(得分:5)
这是因为令牌永远不会被初始化。将其更改为:
Tokens **tokens = malloc(sizeof(Tokens *) * size);
完成后不要忘记释放内存:
for (; i < size; i++) {
free(tokens[i]);
}
free(tokens);
答案 1 :(得分:3)
您有典型的缓冲区溢出情况。
char* code;
分配指向字符的指针(通常为8个字节),而不是用于保存文件数据的缓冲区。
与
相同Token *tokens;
当您在tokens
中写信parse
时,您会覆盖部分堆叠并size
覆盖它。
为他们分配足够的内存!
char * code = malloc(0x1000);
Token *tokens = malloc(0x100 * sizeof(Token *));
传递指针,而不是它的地址:
read_file( path, code );
parse( code, size, tokens );
以下是更正后的代码:
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;
}