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

标签 c malloc free

我目前正在研究 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/

相关文章:

c - 释放使用 calloc 创建的数组时中止(核心转储)

c - 使用 free() 破坏 C 中的 char 数组数据

c - 查找字符串中最长的单词

c - 随机打乱一组字符串

c - C错误输出中高斯函数f(x)= exp(-x ^ 2/2)的蒙特卡洛积分

c - 类型 "void *"的值不能分配给类型 "int **"最后的实体

c - C 上的 MPI,段错误 : 11

c - 字符串 c 中的单词替换

c - 在 malloc 中进行类型转换

c - 为什么在 C 中出现 double free 或 corruption 错误?我释放了我的 mallocs