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

C语言向二进制文件追加int数组时程序崩溃问题排查与修正

代码崩溃原因排查与修复

崩溃原因

  • 未初始化就判断文件指针:FILE* fp;声明后直接执行if(fp == NULL),此时fp是未初始化的随机值,判断无意义且会导致后续逻辑混乱。
  • fread参数错误+非法内存访问:fread(N, sizeof(int), 1, fp);中,fread的第一个参数应为接收数据的缓冲区地址,直接传N(int值)会被当作内存地址,触发非法内存访问,直接导致崩溃。
  • 未处理文件不存在的场景:首次写入时,fopen(filename, "rb")会返回NULL,此时直接调用fread、fclose会操作空指针,引发崩溃。
  • 违反函数返回值语法:函数声明为void,却写了return(N);和return(N, buffer,array);,完全不符合C语言语法,会导致编译错误或运行时异常。
  • 缓冲区固定大小+未检查malloc结果:malloc(sizeof(int)*200)固定了缓冲区容量,若原有数组长度超过200会触发缓冲区溢出;且未检查malloc是否成功,若分配失败buffer为NULL,后续操作会崩溃。
  • 写入逻辑错误:原代码写入缓冲区时仅写入1个int,且新文件长度只写了传入的N,未加上原有数组长度,完全不符合拼接追加的需求。

修正后的代码

#include <stdio.h>
#include <stdlib.h>

void appendIntArray(char* filename, int* array, int N) {
    // 非法输入直接返回
    if (array == NULL || N <= 0) {
        return;
    }

    int existing_len = 0;
    int* buffer = NULL;
    FILE* fp = fopen(filename, "rb");

    if (fp != NULL) {
        // 读取原有数组的长度
        if (fread(&existing_len, sizeof(int), 1, fp) == 1) {
            // 动态分配内存存储原有数组
            buffer = (int*)malloc(sizeof(int) * existing_len);
            if (buffer == NULL) {
                fclose(fp);
                return;
            }
            // 读取原有数组数据
            fread(buffer, sizeof(int), existing_len, fp);
        }
        fclose(fp);
    }

    // 以写入模式打开文件,准备写入合并后的数据
    fp = fopen(filename, "wb");
    if (fp == NULL) {
        free(buffer); // 避免内存泄漏
        return;
    }

    // 写入合并后的总长度
    int total_len = existing_len + N;
    fwrite(&total_len, sizeof(int), 1, fp);

    // 写入原有数组(如果存在)
    if (existing_len > 0 && buffer != NULL) {
        fwrite(buffer, sizeof(int), existing_len, fp);
    }

    // 写入新传入的数组
    fwrite(array, sizeof(int), N, fp);

    fclose(fp);
    free(buffer); // 释放内存,避免泄漏
}

关键修复点说明

  • 输入合法性校验:提前过滤空数组、非法长度的输入,避免无效操作。
  • 正确处理文件不存在的情况:rb模式打开失败时,直接进入新数组写入逻辑,不会操作空指针。
  • 动态内存分配:根据原有数组长度动态分配缓冲区,避免固定大小导致的溢出,同时检查malloc分配结果。
  • 正确的拼接逻辑:先读取原有数组的长度和数据,合并后写入总长度,再依次写入原有数据和新数据,实现追加拼接。
  • 内存泄漏防护:所有分配的内存都会被及时释放,打开文件失败时也会清理已分配的内存。
  • 符合函数语法:严格遵循void函数的要求,不再有非法return语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:50:42