C语言动态内存读取文件时strcat函数失效问题修复
问题根因
代码存在4个核心错误,直接导致strcat工作异常、输出乱码甚至程序崩溃:
- 目标字符数组内存分配错误:
main中定义的char firstS []="";和char secondS []="";本质是长度为1的栈数组,仅能容纳空终止符\0,strcat向其中追加内容时会直接越界写入栈内存,属于未定义行为,这是异常的核心诱因。 - 头文件缺失:代码使用
strcat等字符串处理函数,但未引入<string.h>头文件,会导致函数隐式声明,运行时行为不可预期。 - 文件读取逻辑错误:用
while(!feof(fp))作为循环判断条件会多读取一次无效内容——feof只有在读取操作触发文件结束标记后才会返回真,会导致最后一次fgets读取失败时仍然执行strcat,追加内存中的垃圾值。 - 缓冲区逻辑混乱:函数内
malloc了1000字节的临时缓冲区,但fgets每次最多仅读取99字节到缓冲区,内存分配大小和实际读取长度不匹配,且未对缓冲区做初始化,存在读取脏值的风险。
修复方案
修复思路如下:
- 弃用固定长度的栈数组存储文件内容,改用动态分配的堆内存,根据读取到的内容长度自动扩容,从根源避免内存越界
- 修正
feof的错误用法,直接以fgets的返回值作为循环终止判断条件 - 简化缓冲区逻辑,用固定长度的栈空间做单次读取的临时缓冲区,避免无意义的堆分配
- 所有动态分配的内存在使用完成后及时释放,避免内存泄漏
修复后可正常运行的代码:
#include <stdlib.h> #include <stdio.h> #include <string.h> // 读取文件内容返回堆上分配的字符串,调用方需手动释放内存 char* fileTest (char* filename){ size_t cap = 1024; // 初始分配1024字节存储内容 char* content = (char*)malloc(cap * sizeof(char)); if (content == NULL) { perror("malloc failed"); exit(-1); } content[0] = '\0'; // 初始化为合法空字符串,保证strcat正常工作 char buf[100]; // 单次读取的临时栈缓冲区,每次最多读99字节 FILE *fp = fopen(filename, "r"); if (fp == NULL){ perror("open file failed"); free(content); exit(-1); } // 以fgets返回值判断是否读到文件末尾,规避feof的经典误用问题 while(fgets(buf, sizeof(buf), fp) != NULL) { size_t curLen = strlen(content); size_t readLen = strlen(buf); // 剩余空间不足时自动扩容为原容量的2倍 if (curLen + readLen + 1 > cap) { while (curLen + readLen + 1 > cap) { cap *= 2; } char* tmp = (char*)realloc(content, cap * sizeof(char)); if (tmp == NULL) { perror("realloc failed"); free(content); fclose(fp); exit(-1); } content = tmp; } strcat(content, buf); } fclose(fp); return content; } int main() { char* firstS = fileTest("file.txt"); char* secondS = fileTest("file2.txt"); printf("First file: %s \n", firstS); printf("Second file: %s", secondS); // 释放堆内存 free(firstS); free(secondS); return 0; }
关键注意点
- 所有作为
strcat目标的字符串,必须先初始化为以\0结尾的合法C字符串,且分配的内存大小必须大于等于「已有字符串长度 + 待追加字符串长度 + 1(存储空终止符)」,否则必然触发内存越界。 - 不要使用
while(!feof(fp))编写文件读取循环,这是C语言文件操作的经典错误写法。 - 栈上定义的
char arr[] = ""长度固定为1,仅能存储空字符串,不能用来承载任何非空文本内容。
内容的提问来源于stack exchange,提问作者Ugur A
相关产品推荐
相关产品推荐

