Archived

This topic is now archived and is closed to further replies.

toddhd

Access violation error allocating memory

Recommended Posts

toddhd    115
I am writing a simple RPG program. I created a class called Ccharacter to hold each characters info (name, race, etc.) and a vector called allchars that holds all the current characters. I wrote two functions, one to save all the characters to a binary file, and one to read them back in again. The save function seems to work just fine. But the load function gives an "access violation writing location" error when I try to allocate memory to load the characters back in. Here are my two functions: void SaveCharacters(){ ofstream ofile("chars.dat", std::ios::binary); // First write the number of player characters saved in the file //allchars is the vector that holds the C_character objects int size=allchars.size(); //Write the number of C_characters to save ofile.write((char*)&size , sizeof(size)); // Loop through each C_character and save to file for (loop=0;(int)loop

Share this post


Link to post
Share on other sites
ToohrVyk    1596
If you fail opening the file, the value of charcount will not be changed by the read() call, and you''ll be creating an array of size 0. You could correct this by:

- Setting charcount to 1 instead of 0 (and see if it works)
- Check if charcount is not 0 before creating the array, and if it is, throw an error and stop execution.

Victor Nicollet, INT13 game programmer

Share this post


Link to post
Share on other sites
OmniBrain    148

for (loop=0;(int)loop size = sizeof(allchars[loop]);
ofile.write((char*)&allchars[loop],sizeof(Ccharacter));
}


OUTCH! i have hardly seen a worse coding style before! (no offense, I really have had problems to read this. my eyes still hurt )

you are positive this is the original code you are able to compile? If it does compile, you have to tell me what compiler you use, mine wouldn't eat the for loop. (well, actually it doesn't eat the SaveChar-function at all, bracktes are misplaced)

- your variable "loop" seems not to be declared
- your condition inside the for-loop is totally messed (you asign a value "=" rather than compare values "==", if i can read this at all)
- you put the code to write a char into the for-comand rather than into the for-loop-body.
- the for-body is empty.

ideas on how to bug-hunt (and improve readability of your code)
- use some helper-variables to store temporary results and don't put them directly into a for loop for example.
- use printf() with your helper-variables or debug/trace to check value of helper-variables.

so do not use

for (int index=0; index < allchars.size(); index++)
{}

but


int numberOfCharsToSave = allchars.size();
printf("numbers of saved characters: %d\n", numberOfCharsToSave);
for (int index=0; index < numberOfCharsToSave; index++)
{}



[Edit]You guessed it. Tags messed[/Edit]

[edited by - OmniBrain on May 25, 2004 2:18:59 PM]

Share this post


Link to post
Share on other sites
toddhd    115
Wow, somehow my code got chopped when posting. Let me try again:

void SaveCharacters(){
ofstream ofile("chars.dat", std::ios::binary);

// First write the number of player characters saved in the file
//allchars is the vector that holds the C_character objects
int size=allchars.size();
//Write the number of C_characters to save
ofile.write((char*)&size , sizeof(size));

// Loop through each C_character and save to file
for (loop=0;(int)loop size = sizeof(allchars[loop]);
ofile.write((char*)&allchars[loop],sizeof(Ccharacter));
}
ofile.flush();
ofile.close();
}

void LoadChars(){
ifstream ifile("chars.dat", std::ios::binary);
//TODO:Need to add some error handling here, in case of no file, or corrupted file

//find out how many characters to read
int charcount = 0;
ifile.read((char*)&charcount, sizeof(charcount));

Ccharacter *value = new Ccharacter[charcount];

//for(loop=0;(int)loop<(int)charcount;loop++){
//ifile.read((char*)value, sizeof(Ccharacter));
//allchars.push_back(value[loop]);
//}
//delete [] value;
ifile.close();
}


I wish I could "preview" on this forum. Anyway, yes, loop is defined elsewhere. And I verified that the charcount is being read correctly. (there are 3 characters saved, and it is reading a 3). I commented out the lines that read in the character data just to troubleshoot (I am not sure about those yet anyway). So all it should do for now is read in a value (which it does correctly), allocate some space, and then delete that space.

Share this post


Link to post
Share on other sites
toddhd    115
Sorry, my code is still getting chopped. How do I post code on this forum without it getting cut off? I''ve seen some posts where the code shows up in nice white scolling boxes for example...

Share this post


Link to post
Share on other sites
toddhd    115
I also posted this same question on Experts Exchange, you can see the correct code there...
http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_21001713.html#11154588

Share this post


Link to post
Share on other sites
toddhd    115

void SaveCharacters(){
ofstream ofile("chars.dat", std::ios::binary);

// First write the number of player characters saved in the file

//allchars is the vector that holds the C_character objects

int size=allchars.size();
//Write the number of C_characters to save

ofile.write((char*)&size , sizeof(size));

// Loop through each C_character and save to file

for (loop=0;(int)loop<allchars.size();loop++){
size = sizeof(allchars[loop]);
ofile.write((char*)&allchars[loop],sizeof(Ccharacter));
}
ofile.flush();
ofile.close();
}

void LoadChars(){
ifstream ifile("chars.dat", std::ios::binary);
//TODO:Need to add some error handling here, in case of no file, or corrupted file


//find out how many characters to read

int charcount = 0;
ifile.read((char*)&charcount, sizeof(charcount));

Ccharacter *value = new Ccharacter[charcount];

//for(loop=0;(int)loop<(int)charcount;loop++){

//ifile.read((char*)value, sizeof(Ccharacter));

//allchars.push_back(value[loop]);

//}

//delete [] value;

ifile.close();
}


Any better?

Share this post


Link to post
Share on other sites
OmniBrain    148
All i have is a vague idea what can be going on wrong, but i had to see the constructors of your Cchars to verify it.

My guess is you used new Cchar(somevariables) to create the chars you saved. this works, but then you try to allocate an array of Cchars with new. this will use the parameterless constructor, which i guess is messed...

if you tell me now you used "new Cchar[3]" before to create the chars you saved in SaveCharacters, I am lost...

Share this post


Link to post
Share on other sites
toddhd    115
My problem might be that I have a vector object and some strings in my Ccharacter class. Also, the vector stores types a Citem, which is another class in my code. It represents what items a character is carrying. Here is some pseudo code:

Ccharacter::Ccharacter(void) // Here is the contructor, I noted the variable declarations from the *.h file below

{
Name="?????"; //string Name

Race="?????"; //string Race

Class="?????"; //string Class

Strength=0; //int Strength

...
...
Items.clear(); //vector<Citem> Items

}


I'll be happy to post the entire thing if it will help you, although all the other variables are strings or integers.

I have a global vector in my program called "allchars":
vector<Ccharacter> allchars; 


As each new character is created, I use allchars.push_back to add them to the character list. Then I call SaveCharacters() to save them all out to the file. This acutally seems to work well, although it is hard to verify what is getting written, since it is in binary, and I can't yet read it back in.



[edited by - toddhd on May 25, 2004 3:00:42 PM]

Share this post


Link to post
Share on other sites
OmniBrain    148
resigning on this. can''t help any further without more source and probably tracing through it.
(no, don''t post it, i am out of time)

I suggest you start in your debugger and trace trough your constructor, you will see the line where it crashes and should get a good idea why it fails.

Share this post


Link to post
Share on other sites
toddhd    115
Thanks tons for everyone''s help on this. Bottom line was that trying to save Classes containing dynamic variables such as string and vector is just a no-no. At least, it is in the manner that I was attempting to do it.

Rather than write out a complicated save function, I just converted all the strings and vectors to arrays and let it be.

Now it works like magic, and I can save and load character data with ease.

Thanks again.

Share this post


Link to post
Share on other sites