You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何给char缓冲区末尾赋值空终止符后无法释放内存?

赋值空终止符后free报错的原因及修复

核心问题:内存越界访问

你只给缓冲区分配了length字节的内存,而数组下标从0开始,所以缓冲区的有效访问范围是buffer[0]到buffer[length-1]。buffer[length] = '\0';这行代码直接写入了超出分配范围的内存位置,属于未定义行为——这种操作会破坏内存管理的内部结构,等到free时系统检测到内存块被非法修改,就会触发报错。

为什么不加这行时free能正常执行?因为没触碰越界内存,内存管理的元数据没被破坏,所以free可以正常完成(但此时用printf("%s", t)输出字符串存在风险:没有终止符的情况下,程序会一直读取内存直到遇到随机的\0,可能输出乱码或触发其他问题)。

修复方案

分配内存时多预留1字节用于存储空终止符:

buffer = malloc((size_t)length + 1);

这样buffer[length]就属于合法的内存范围,赋值\0后再free就不会报错。

原代码的其他隐患

除了内存越界,原代码还有几个容易导致崩溃的问题:

  • fopen失败后没有终止函数,后续会继续执行fseek、ftell等操作,直接操作NULL指针导致崩溃
  • malloc失败后没有终止函数,后续操作NULL指针也会出问题
  • ftell返回的long类型和malloc要求的size_t类型不匹配,需要做类型转换避免溢出风险
  • fread没有校验读取的字节数,可能出现文件未完全读取的情况

修复后的完整代码

char *readFileToString(const char *file)
{
    char *buffer = NULL;
    long length;
    FILE *f = fopen(file, "rb");

    if (f == NULL) {
        printf("ERROR::FILE:FILE_NOT_SUCCESFULLY_READ\n");
        return NULL;
    }

    if (fseek(f, 0, SEEK_END) != 0) {
        printf("ERROR::FILE:FAILED_TO_SEEK_END\n");
        fclose(f);
        return NULL;
    }

    length = ftell(f);
    if (length == -1) {
        printf("ERROR::FILE:FAILED_TO_GET_FILE_LENGTH\n");
        fclose(f);
        return NULL;
    }

    if (fseek(f, 0, SEEK_SET) != 0) {
        printf("ERROR::FILE:FAILED_TO_SEEK_START\n");
        fclose(f);
        return NULL;
    }

    // 多分配1字节用于存储空终止符
    buffer = malloc((size_t)length + 1);
    if (buffer == NULL) {
        printf("Error allocating buffer memory\n");
        fclose(f);
        return NULL;
    }

    size_t read_bytes = fread(buffer, 1, (size_t)length, f);
    if (read_bytes != (size_t)length) {
        printf("ERROR::FILE:FAILED_TO_READ_FULL_CONTENTS\n");
        free(buffer);
        fclose(f);
        return NULL;
    }

    fclose(f);
    buffer[length] = '\0'; // 合法访问,不会破坏内存结构

    return buffer;
}

int main()
{
    char *t = readFileToString("test");
    if (t != NULL) {
        printf("%s", t);
        free(t); // 正常释放无报错
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Aidan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 07:53:20