使用C的free是将数据保存在本地字符串中

时间:2014-11-17 14:17:31

标签: c malloc free

我目前正在通过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语言进行过多次编程,但我发现这种行为在许多层面都令人费解。在内存分配和免费方面,我错过了什么?

1 个答案:

答案 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';