C语言中fputs触发corrupted size vs prev_size错误致程序崩溃求助
修复fputs崩溃及内存错误问题
核心问题分析
FILE指针的错误操作
- 手动
mallocFILE指针完全多余,fopen会直接返回合法的FILE指针。后续把fopen结果赋值给这个malloc出来的指针,导致原malloc内存泄漏;最后用free释放fopen返回的指针更是错误——FILE指针必须用fclose释放,不能用free。
- 手动
文件名处理的致命错误
strtok(source_file_name, ".")会直接修改传入的源文件名字符串,把第一个.改成\0。如果循环中有多个符合条件的标签,第二次调用strtok时会处理已被破坏的字符串,引发未定义行为;若传入的源文件名是字符串常量,修改它直接会导致崩溃。- 每次找到标签就用
"w"模式重新打开文件,会清空之前写入的内容,最终文件里只会剩下最后一个标签的数据。
错误行判断逻辑错误
- 当前代码只要
error_flag_line为1,就跳过所有循环迭代,这显然不符合逻辑——应该是跳过对应行有错误的标签,比如error_flag_line[j] == 1(假设这是存储每行错误状态的数组)。
- 当前代码只要
修正后的代码
void entry_file_creation(int lc, int *error_flag_line, char *source_file_name) { int j = 0; FILE *entry_ptr = NULL; char ent_filename[256]; // 用缓冲区存储目标文件名,避免修改原字符串 // 安全处理文件名:复制原字符串后再截断,避免破坏输入 char *base_name = strdup(source_file_name); if (base_name == NULL) { fprintf(stderr, "\nError: failed to process file name\n"); exit(-1); } strtok(base_name, "."); // 截断到第一个.之前的部分 snprintf(ent_filename, sizeof(ent_filename), "%s.ent", base_name); free(base_name); // 释放复制的内存 // 一次性打开文件,避免反复清空内容 entry_ptr = fopen(ent_filename, "w"); if (entry_ptr == NULL) { fprintf(stderr, "\nError: can't create entry file '%s'\n", ent_filename); exit(-1); } while (j < lc) { // 跳过当前行有错误的标签(假设error_flag_line是每行的错误状态数组) if (error_flag_line != NULL && error_flag_line[j] == 1) { j++; continue; } if (label_table[j].extern_entry == 2) { printf("\nLabel: %s \n", label_table[j].name); fputs(label_table[j].name, entry_ptr); fputs("\t", entry_ptr); fprintf(entry_ptr, "%d\n", label_table[j].address); } j++; } // 关闭文件,释放资源 fclose(entry_ptr); }
关键修正说明
- 用
strdup复制原文件名,避免直接修改传入的字符串,防止破坏原始数据或触发常量字符串修改的未定义行为。 - 用
snprintf生成目标文件名,比strcat更安全,避免缓冲区溢出。 - 只打开一次
.ent文件,循环写入所有符合条件的标签,确保所有数据都能保留。 - 移除了错误的
malloc和free操作,改用fclose正确关闭文件。 - 调整了错误行判断逻辑,使其针对当前迭代的行进行检查。
内容的提问来源于stack exchange,提问作者Eitan Ratner
相关产品推荐
相关产品推荐

