C++读取Doom WAD文件异常:读取指针地址而非正确值排查
Doom WAD文件读取异常原因分析
第一段代码返回随机字节的原因
核心问题是类成员初始化顺序错误:
在Wad类的私有成员声明中,顺序为:
private: fstream wadFile; string wadName; WadHeader headerInfo;
C++规定,类成员的初始化顺序由其在类中的声明顺序决定,与构造函数初始化列表的书写顺序无关。你的Wad构造函数初始化列表写为Wad(string wn) : wadName(wn), headerInfo(wadFile),但实际初始化顺序是wadFile(默认构造)→ wadName(传入参数初始化)→ headerInfo(传入wadFile初始化)。
这意味着headerInfo初始化时,wadFile只是一个未打开任何文件的空流,此时对其执行read操作会读取无效的随机内存数据,最终返回随机字节。
第二段代码首字节显示0xFF的原因
同样源于成员初始化顺序错误,且传递了未就绪的文件流指针:Wad类的私有成员声明顺序为:
private: fstream wadFile; WadHeader headerInfo; string wadName;
初始化时headerInfo会先于wadName被构造,此时wadFile仅完成默认构造,还未调用open方法打开目标文件。调用wadFile->get()时,因流未关联有效文件,get()会返回EOF(值为-1),而你用unsigned char接收该值,转换后就变成了0xFF,因此显示首字节为0xFF。
额外注意事项
WAD文件的头部数据(如lump数量、目录偏移)采用小端字节序,直接用read读取到unsigned int变量中,在大端字节序的机器上会得到错误值。后续修复时需手动处理字节序转换,示例代码如下:
unsigned int readLittleEndianUint(fstream& file) { unsigned char bytes[4]; file.read(reinterpret_cast<char*>(bytes), 4); return (bytes[0]) | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); }
内容的提问来源于stack exchange,提问作者Golden Star
相关产品推荐
相关产品推荐

