我已经试着解决这个问题好几天了,但是不能让它工作。我在一个std::string析构函数的方法“orphan_all”中得到了一个访问冲突,这个析构函数是从编译器生成的POD结构调用的,它包含一些std::string。
struct SaveData
{
SaveData()
{
MusicStage = GameState::MusicStage;
MusicSubStage= GameState::MusicSubStage;
PlotStage = GameState::PlotStage;
PlotSubStage = GameState::PlotSubStage;
GameStage = GameState::GameStage;
GameSubStage = GameState::GameSubStage;
PlayerLife = 100.0f;
PlayerSuitEnergy = 100.0f;
CurrentPower = 0;
PlayerPos = XMFLOAT3(0,0,0);
CurrentGun = 0;
Guns = 0;
ModsL1 = 0;
ModsL2 = 0;
ModsL3 = 0;
ModsL4 = 0;
CurrentBulletMod = (uint)BulletMod::NoMod;
ElectricModMult = 1.0;
ExplosiveModMult = 1.0;
CorrosiveModMult = 1.0;
}
string MusicStage;
string MusicSubStage;
string PlotStage;
string PlotSubStage;
string GameStage;
string GameSubStage;
float PlayerLife;
float PlayerSuitEnergy;
uint CurrentPower;
XMFLOAT3 PlayerPos;
uint CurrentGun;
uint CurrentBulletMod;
float ElectricModMult;
float ExplosiveModMult;
float CorrosiveModMult;
uint Guns;
uint ModsL1;
uint ModsL2;
uint ModsL3;
uint ModsL4;
};
struct FileData
{
uint64 Hash;
uint Version;
SaveData Data;
};
这就是结构。当调用该对象的析构函数时,如下所示:
HRESULT SavesIO::LoadGameFile(const std::string& FileName,SaveData& Data)
{
ifstream file;
file.open(FileName,ios::binary);
if(file.is_open())
{
FileData fdata;
file.read((char*)&fdata,sizeof(FileData));
if(fdata.Hash != GameHash)
{
cout << "Corrupt Savegame : " << FileName << endl;
return CheckHR(HR_Fail);
}
if(fdata.Version > CurrentVersion)
{
cout << "Savegame version is greater than game version : " << FileName << endl;
return CheckHR(HR_Fail);
}
Data = fdata.Data;
return HR_Correct;
}
cout << "Savegame : " << FileName << "not found" << endl;
return CheckHR(HR_Invalid_Arg);
}
在“orphan_all”中发生了访问冲突,该冲突是从“fdata”中“Data”中字符串的析构函数调用的,它显示的位置类似于“0xdddddddd”或“0xFEEEEEEE”,因此出于某种原因,它似乎调用了一些已删除的数据。我使用HeapValidate检查了堆损坏()和_Crt检查内存()而且一切似乎都很好。如果我在发行版中编译,问题就会消失。有人知道吗?我的系统是Windows 8 Pro x64,使用Visual Studio Express 2012,使用v110工具集进行编译。
编辑:我将数据写成这样:
void SavesIO::SaveGameFile(SaveData Data,const std::string& FileName)
{
ofstream file;
file.open(FileName,ios::binary);
FileData fdata;
fdata.Hash = GameHash;
fdata.Version = CurrentVersion;
fdata.Data = Data;
file.write((char*)&fdata,sizeof(FileData));
file.close();
}
3条答案
按热度按时间khbbv19g1#
_ITERATOR_DEBUG_LEVEL
似乎是导致调试模式崩溃的原因。我并不反对你的解决方案。相反,这是最好的办法。但是,下面是GoodToKnow:
#define _ITERATOR_DEBUG_LEVEL 0
或者(更好的)在项目的预编译器定义中设置它。这将停止STL以引发异常...参考:https://msdn.microsoft.com/en-us/library/hh697468.aspx
确保所有嵌套/相关项目都是使用相同的选项编译的,或者:_iterator_debug_level value '0' doesn't match value '2'
此定义默认值为2。
PS看起来微软仍然在编译他们内部开发的STL,甚至在工具集v120中
vxqlmq5t2#
这是IInspectable所说的内容,但我不能将其标记为答案,因为它是一个注解。我的write和read函数现在看起来如下:
我读者:
我还有最后一个问题。如果一个用户试图把他的存档从一台32位的电脑转移到一台64位的电脑上,我会遇到什么问题呢?字节序可能不是问题,因为游戏是windows专用的。无论如何,谢谢你,你节省了我很多时间。
dced5bon3#
我得到了
AccessViolation
和xmemory
std::string
析构函数的调用堆栈,因为我将string
从用Debug
编译的程序集传递到另一个用Release
编译的程序集。