Sign in to follow this  

only on DEBUG this code crashes

This topic is 2345 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[code]
int main()
{
ifstream _file_input("GameData.dat", ios::binary);
for (int _idx = 0; _idx < 3; _idx++)
{
//cout<<"size of Monster "<<sizeof(GameMonster)<<" ";
//cout<<"current seek pointer position :"<<_file_input.tellg()<<endl;

//_file_input.seekg(_idx * sizeof(GameMonster));
_file_input.read((char*)&_monster, sizeof(GameMonster));

cout<<_monster.Damage<<" "<<_monster.Hp<<" "<<_monster.Name<<endl;
}

_file_input.close();

cout<<"\nPress a key"<<endl;
getchar();
// PAST THIS LINE THE PROGRAM CHRASHES
}
[/code]

the error
Unhandled exception at 0x581fad4a (msvcp100d.dll)
0xC0000005: Access violation reading location 0x00a94be4

if I switch to release the code runs just fine, pretty weird huh?

Share this post


Link to post
Share on other sites
It's not weird, it's common of bugs relating to uninitialized memory, or memory corruption -- the debug build includes extra checks to try and [i]make [/i]bad code crash, so that you realize that you've got some kind of corruption going on.

Where/what is [font="Lucida Console"]_monster[/font]?

Share this post


Link to post
Share on other sites
Is _monster really an object of class/struct GameMonster? And what type are Damage, Hp and Name members of _monster object?
Are there some other global variables with non-trivial constructor or destructor in your program?

Share this post


Link to post
Share on other sites
Whether or not it's weird depends on what your GameMonster type looks like. If it's non-POD, then it's not weird at all.

Share this post


Link to post
Share on other sites
heres the full soruce

maybe something Im missing?

[code]


#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>

using namespace std;

class GameMonster
{
public:
string Name;
int Hp;
int Damage;

GameMonster() { Name = ""; Hp = 0; Damage = 0; }
GameMonster(string name, int hp, int dmg) { Name = name; Hp = hp; Damage = dmg; }
};


class GameNpc
{
public:
string Name;
int Hp;
int Damage;
string SpecialAttack;

GameNpc() { Name = ""; Hp = 0; Damage = 0; SpecialAttack = ""; }
GameNpc(string name, int hp, int dmg, string specialAtk) { Name = name; Hp = hp; Damage = dmg; SpecialAttack = specialAtk; }
};



void main()
{
GameMonster _monster;
GameMonster _monsters[3] = { GameMonster("Troll", 50, 20), GameMonster("Skeleton", 10, 5), GameMonster("Rat", 5, 1) };
GameNpc _npcs[3] = { GameNpc("Gawein", 100, 25, "Smity"), GameNpc("Vivi", 25, 5, "LulzSkillz"), GameNpc("Necro", 40, 2, "Raise Dead") };

ofstream _file("GameData.dat", ios::binary);

_file.write((char*)_monsters, sizeof(_monsters));

_file.seekp(0, ios::end);
cout<<"size of GameData.dat "<<_file.tellp()<<" bytes"<<endl<<endl;

_file.close();



ifstream _file_input("GameData.dat", ios::binary);
for (int _idx = 0; _idx < 3; _idx++)
{
cout<<"size of Monster "<<sizeof(GameMonster)<<" ";
cout<<"current seek pointer position :"<<_file_input.tellg()<<endl;

//_file_input.seekg(_idx * sizeof(GameMonster));
_file_input.read((char*)&_monster, sizeof(GameMonster));

cout<<_monster.Damage<<" "<<_monster.Hp<<" "<<_monster.Name<<endl;
}

_file_input.close();

cout<<"\nPress a key"<<endl;
getchar();
}
[/code]

Share this post


Link to post
Share on other sites
std::string is non-POD, and since your classes contain it, your classes are non-POD. This means that you can't just copy the bits that make it up to a file and read it back. You need to do actual serialization.

Share this post


Link to post
Share on other sites
[url=http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html]The first link when I put "POD C++" into google[/url].

Share this post


Link to post
Share on other sites
The links says nothing about how to fix the problem so Ill ask again

should I use fixed char arrays instead or is there an actual way of reading std::strings of variable size using ifstream

<div><br></div><div><br></div><div>edit: I just tried using very long strings just to test what happened if I varied each of the monsters actual byte size but it still working properly (without considering the crash at the end of program)</div>

Share this post


Link to post
Share on other sites
[quote name='EvilNando' timestamp='1310899151' post='4836318']
should I use fixed char arrays instead or is there an actual way of reading std::strings of variable size using ifstream
[/quote]
[url=http://www.parashift.com/c++-faq-lite/serialization.html]The first link when I throw "C++ serialization" into google[/url].

Share this post


Link to post
Share on other sites
You can use std::string, all you have to do is writing each variable in GameMonster one at a time

[code]#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <fstream>

using namespace std;

class GameMonster
{
public:
string Name;
int Hp;
int Damage;

GameMonster() { Name = ""; Hp = 0; Damage = 0; }
GameMonster(string name, int hp, int dmg) { Name = name; Hp = hp; Damage = dmg; }
};



int main()
{
GameMonster _monster;
GameMonster _monsters[3] = { GameMonster("Troll", 50, 20), GameMonster("Skeleton", 10, 5), GameMonster("Rat", 5, 1) };

ofstream _file("GameData.dat", ios::binary);

for (int i = 0; i < 3; i++)
{
int nameLength = _monsters[i].Name.size();
_file.write((char*)&nameLength, sizeof(int));
_file.write(_monsters[i].Name.c_str(), _monsters[i].Name.size());
_file.write((char*)&_monsters[i].Hp, sizeof(int));
_file.write((char*)&_monsters[i].Damage, sizeof(int));
}


_file.seekp(0, ios::end);
cout<<"size of GameData.dat "<<_file.tellp()<<" bytes"<<endl<<endl;

_file.close();


ifstream _file_input("GameData.dat", ios::binary);
for (int _idx = 0; _idx < 3; _idx++)
{
cout<<"size of Monster "<<sizeof(GameMonster)<<" ";
cout<<"current seek pointer position :"<<_file_input.tellg()<<endl;

int nameLength;
_file_input.read((char*)&nameLength, sizeof(int));
_monster.Name.resize(nameLength);
_file_input.read(&_monster.Name[0], nameLength);
_file_input.read((char*)&_monster.Hp, sizeof(int));
_file_input.read((char*)&_monster.Damage, sizeof(int));

cout<<_monster.Damage<<" "<<_monster.Hp<<" "<<_monster.Name<<endl;
}

_file_input.close();

cout<<"\nPress a key"<<endl;
getchar();
}[/code]

Share this post


Link to post
Share on other sites
To make it easier, consider writing helper functions:
[code]
// Some IO Helper header
namespace detail
{
template<typename Type>
std::istream &readPOD(std::istream &in, Type &instance)
{
char *pointer = reinterpret_cast<char *>(&instance);
return in.read(pointer, sizeof(instance));
}

template<typename Type>
std::ostream &writePOD(std::ostream &out, const Type &instance)
{
const char *pointer = reinterpret_cast<const char *>(&instance);
return out.write(pointer, sizeof(instance);
}
}

std::istream &read(std::istream &in, int &i)
{
return detail::readPOD(in, i);
}

std::istream &read(std::istream &in, std::string &s)
{
int count;
if(read(in, count))
{
vector<char> data;
data.resize(count);
if(in.read(&data.front(), count))
{
s.assign(data.begin(), data.end());
}
}
return in;
}

std::istream &write(std::ostream &out, int i)
{
return detail::write(out, i);
}

std::istream &write(std::ostream &out, const std::string &s)
{
int n = s.size();
write(n);
return out.write(s.c_str(), n);
}

// Monster

void read(std::istream &in, Monster &monster)
{
if(!(read(monster.Hp) && read(monster.Damage) && read(monster.Name)))
{
// error handling?
}
}

void write(std::ostream &out, const Monster &monster)
{
if(!(write(monster.Hp) && write(monster.Damage) && write(monster.Name)))
{
// error handling?
}
}
[/code]

Share this post


Link to post
Share on other sites

This topic is 2345 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this