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
相关产品推荐
相关产品推荐

