第二次调用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
相关产品推荐
相关产品推荐

