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

C语言逐行读文件时malloc触发Access violation writing location错误

问题原因

你的代码存在3个直接触发崩溃+逻辑错误的问题:

  1. 参数类型完全不匹配:你定义的filePath是char*类型,仅用来存储文件路径字符串,但fgetc、fgets等文件操作函数要求传入的入参是fopen()返回的FILE*类型文件流指针。直接把路径字符串传给这些函数,会让函数把普通字符串的内存地址当作内部FILE结构体地址解析,从一开始就会触发非法内存访问。
  2. 缺失头文件导致指针截断:代码没有引入<stdlib.h>头文件,malloc函数没有前置声明。在64位编译环境下,未声明的函数会被默认按返回32位int处理,malloc返回的64位堆地址会被截断,再经过符号扩展就会生成你异常信息里0xFFFFFFFFEA1854F0这种高位全为F的非法用户态地址,向这个地址写数据必然触发访问违规。这也是你觉得"代码没改突然坏了"的常见诱因——可能之前是32位编译配置,切到64位编译后隐式声明的问题直接暴露。
  3. 读取逻辑错误:循环里调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:18:09