我目前正在研究 buildyourownlisp.com并且在解析 float 时遇到了问题。这是相关的功能:
lval* lval_read_float(mpc_ast_t* ast) {
errno = 0;
char* float_string;
float_string = (char *) malloc(1);
for (int i = 0; i < ast->children_num; i++) {
char* child = ast->children[i]->contents;
float_string = realloc(float_string, sizeof(float_string) + sizeof(child));
strcat(float_string, child);
}
printf("Assembled string: %s\n", float_string);
float x = strtod(float_string, NULL);
free(float_string);
printf("Float: %f\n", x);
return errno != ERANGE ? lval_float(x) : lval_err("Invalid float");
}
当我不 free() float_string 时,这基本上按预期工作。当我添加对 free(float_string) 的调用时,数据存储在 lval_read_float() 调用之间的局部变量中。例如,如果我运行:
lispy> + 2.5 2.5
我将收到输出:
Assembled string: 2.5
Float: 2.500000
Assembled string: 2.52.5
Float: 2.520000
虽然我用 C 编写的程序不多,但我发现这种行为在很多层面上都令人费解。关于内存分配和释放,我错过了什么?
最佳答案
您将 sizeof()
运算符应用于指针,这将为您提供 POINTER 的大小,而不是字符串。请改用 strlen()
,它将正常工作。
替换:
float_string = realloc(float_string, sizeof(float_string) + sizeof(child));
与:
float_string = realloc(float_string, strlen(float_string) + strlen(child) + 1);
末尾的额外“+1”用于终止字符“\0”,strlen()
不计算在内。
如下@mah 所述,您还需要在首次使用之前初始化内存以使循环正常工作。这就是为什么在下面:
float_string = (char *) malloc(1);
你应该添加:
*float_string = '\0';
关于c - 使用 C 的 free 是将数据保存在本地字符串中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26974697/