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

第二次调用fopen读取文件时程序无报错崩溃问题求助

问题分析与修复方案

核心错误点

  • FILE指针错误分配:代码中FILE* f = new FILE;是完全错误的用法。FILE是C标准库的文件结构体,不需要也不能用C++的new分配,fopen会直接返回合法的FILE指针(失败时返回nullptr)。这行代码会造成内存泄漏,且fopen失败时调用fclose(f)会触发空指针崩溃。
  • malloc分配带vector的结构体:malloc仅分配内存空间,不会调用成员变量(vector<triangle> tris)的构造函数,导致vector处于未初始化的非法状态,后续赋值操作会破坏内存,引发二次调用崩溃。
  • 错误的空指针处理:fopen返回nullptr时执行fclose(f),属于对空指针的非法操作,直接导致程序崩溃。

修复后的代码

修正后的loadObj函数

vector<triangle> loadObj(const char* sfileName){
    // 直接通过fopen获取文件指针,无需new分配FILE
    FILE* f = fopen(sfileName,"r");

    if(f==nullptr){
        // 空指针不能调用fclose,直接返回空容器
        return {};
    }
    vector<vec3d> ve;
    vec3d v;
    vector<triangle> cache;
    char line[100];

    while (fgets(line, sizeof(line), f)) {
        strstream s;
        s << line;
        char junk;
        if(line[0]=='v'){
            s >> junk >> v.x >> v.y >> v.z;
            ve.push_back(v);
        }
        else if(line[0]=='f'){
            int p1,p2,p3;
            s >> junk >> p1 >> p2 >> p3;
            // 增加索引合法性检查,避免越界访问
            if(p1 > 0 && p1 <= ve.size() && p2 >0 && p2 <= ve.size() && p3>0 && p3<=ve.size()){
                triangle t;
                t.vertexs[0] = ve[p1-1];
                t.vertexs[1] = ve[p2-1];
                t.vertexs[2] = ve[p3-1];
                cache.push_back(t);
            }
        }
    }
    fclose(f);
    return cache;
}

修正后的loadMesh函数

mesh* loadMesh(const char* file){
    // 用new分配mesh,自动调用成员vector的构造函数
    mesh* cubo = new mesh;
    if (cubo == nullptr){
        return nullptr;
    }
    cubo->tris = loadObj(file);
    return cubo;
}

额外注意事项

  • 读取OBJ文件时,必须处理f行索引越界的情况(比如文件中索引大于已读取的顶点数),否则会触发未定义行为。
  • 后续释放mesh时,需用delete而非free,否则vector的析构函数不会被调用,会造成内存泄漏。

内容的提问来源于stack exchange,提问作者Dalton Gomes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:30:15