我目前正在通过buildyourownlisp.com工作,并在我解析浮动时遇到了问题。这是相关的功能:
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");
}
当我没有释放()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语言进行过多次编程,但我发现这种行为在许多层面都令人费解。在内存分配和免费方面,我错过了什么?
答案 0 :(得分:4)
您将sizeof()
运算符应用于指针,它将为您提供POINTER的大小,而不是字符串。请改用strlen()
,它会正常工作。
替换:
float_string = realloc(float_string, sizeof(float_string) + sizeof(child));
使用:
float_string = realloc(float_string, strlen(float_string) + strlen(child) + 1);
额外&#34; + 1&#34;最后是终止&#39; \ 0&#39;字符,不计入strlen()
。
正如下面提到的@mah,您还需要在首次使用之前初始化内存,以使循环正常工作。这就是为什么低于这个原因:
float_string = (char *) malloc(1);
你应该添加:
*float_string = '\0';