C变量无法解释的变化

cod*_*iac 5 c printf pointers

我写了一个简单的C程序转换charTokens.事情很好但我无法理解为什么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)

Ser*_* L. 4

您有一个典型的缓冲区溢出案例。

char* code;
Run Code Online (Sandbox Code Playgroud)

分配一个指向字符(通常为 8 个字节)的指针,而不是保存文件数据的缓冲区。

与相同

Token *tokens;
Run Code Online (Sandbox Code Playgroud)

当您写入时,tokensparse会覆盖堆栈的一部分并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)