C语言逐行读文件时malloc触发Access violation writing location错误
问题原因
你的代码存在3个直接触发崩溃+逻辑错误的问题:
- 参数类型完全不匹配:你定义的
filePath是char*类型,仅用来存储文件路径字符串,但fgetc、fgets等文件操作函数要求传入的入参是fopen()返回的FILE*类型文件流指针。直接把路径字符串传给这些函数,会让函数把普通字符串的内存地址当作内部FILE结构体地址解析,从一开始就会触发非法内存访问。 - 缺失头文件导致指针截断:代码没有引入
<stdlib.h>头文件,malloc函数没有前置声明。在64位编译环境下,未声明的函数会被默认按返回32位int处理,malloc返回的64位堆地址会被截断,再经过符号扩展就会生成你异常信息里0xFFFFFFFFEA1854F0这种高位全为F的非法用户态地址,向这个地址写数据必然触发访问违规。这也是你觉得"代码没改突然坏了"的常见诱因——可能之前是32位编译配置,切到64位编译后隐式声明的问题直接暴露。 - 读取逻辑错误:循环里调用
fgetc读取的字符没有存回、也没有回退流位置,会直接吃掉每一行的第一个字符,和你逐行读取的预期完全不符。
另外代码还存在内存泄漏问题:每次循环给str分配的堆内存既没有释放,也没有传递到循环外使用,下一轮循环指针被覆盖后就再也无法回收。
修复方法
- 引入缺失的
<stdlib.h>头文件 - 用
fopen()打开目标文件,先校验文件是否打开成功再执行读取操作 - 直接用
fgets()的返回值作为循环结束判断条件,丢弃错误的fgetc预读逻辑 - 所有堆内存使用完及时释放,文件操作结束后调用
fclose()关闭流
修复后的可运行代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> // 必须引入,否则malloc隐式声明会导致64位下指针截断 #define MAX_STR_SIZE 10000 int main(void) { const char* filePath = "你的目标文件路径"; // 替换为实际路径 // 打开文件,获取FILE*流指针 FILE* fp = fopen(filePath, "r"); if (fp == NULL) { perror("文件打开失败"); return 1; } char tempStr[MAX_STR_SIZE] = {0}; // 直接用fgets返回值判断是否读到文件末尾 while (fgets(tempStr, MAX_STR_SIZE, fp) != NULL) { // 去掉末尾换行符 tempStr[strcspn(tempStr, "\n")] = '\0'; // 分配堆内存存储行内容 char* str = malloc(strlen(tempStr) + 1); if (str == NULL) { perror("内存分配失败"); break; } strcpy(str, tempStr); // 这里写你处理str的业务逻辑 // printf("读取行:%s\n", str); // 用完及时释放内存,避免泄漏 free(str); str = NULL; } // 关闭文件流 fclose(fp); fp = NULL; return 0; }
内容的提问来源于stack exchange,提问作者Yoav Raman
相关产品推荐
相关产品推荐

