char/string ambiguity causing crash?

I'm getting an odd crash whenever I close my program that seems to be caused by a string not de-allocating itself properly.

A bit of research indicates it may be related to some ambiguity between char and string types when reading from a binary file. (Something about char[] vs string()?) I have no idea what needs to be done to fix it, though.

Write code:
1
2
3
4
5
6
7
SaveFile.open(filename.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
	if (SaveFile.is_open()) {
		SaveFile.write(reinterpret_cast<char*>(&SaveData[i].FileID), sizeof(int));
		std::streamsize filenamesize = sizeof(SaveData[i].Name);
		SaveFile.write(reinterpret_cast<char*>(&filenamesize), sizeof(std::streamsize));
		SaveFile.write(reinterpret_cast<char*>(&SaveData[i].Name), filenamesize);
...


Read code:
1
2
3
4
5
6
7
SaveFile.open(filename.c_str(), std::ios::in | std::ios::binary);
	if (SaveFile.is_open()) {
		SaveFile.read(reinterpret_cast<char*>(&SaveData[i].FileID), sizeof(int));
		std::streamsize filenamesize;
		SaveFile.read(reinterpret_cast<char*>(&filenamesize), sizeof(std::streamsize));
		SaveFile.read(reinterpret_cast<char*>(&SaveData[i].Name), filenamesize);
...


SaveData[i].Name is the offending string. What did I mess up here?
smallest compileable example please.
I put one together and it's not getting the error, so I guess the problem lies elsewhere.

The error message is:
Exception thrown at 0x000000013FC7B41A in ghostnun.exe: 0xC0000005: Access violation writing location 0x00000C0000283898.

Here's the call stack: https://i.imgur.com/3q9Mkuf.png

"Name" is the only string in GameSaveData's class.

If the file it's attempting to load doesn't exist, and therefore "Name" is never written to, the error doesn't occur, which led me to believe it was a problem with the fstream code. I guess not.

I don't know where to look next.
You must realize that I cannot help you because you did not show any code.

But it could very much be possible that the code that you have shown first is the problem because to me it seems like a mess.

You should also note that invalid accesses do not always cause exceptions, it is just meerly undefined behavior. So are you using the same flags in the small demo as your full project?

Try to use a different method of serialization, for example just a dumb and simple stream into the file.
Here's the demo code if you're curious.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string>
#include <fstream>

class GameSaveData {
public:
	std::string Name;
};

GameSaveData SaveData[10];
std::fstream SaveFile;

int main(int argc, char* args[])
{
	for (int i = 0; i < 10; i++) {
		SaveData[i].Name = "Testing" + std::to_string(i);

		SaveFile.open("testing.txt", std::ios::out | std::ios::binary | std::ios::trunc); 
		if (SaveFile.is_open()) {
			std::streamsize filenamesize = sizeof(SaveData[i].Name);
			SaveFile.write(reinterpret_cast<char*>(&filenamesize), sizeof(std::streamsize));
			SaveFile.write(reinterpret_cast<char*>(&SaveData[i].Name), filenamesize);
			SaveFile.close();
			SaveFile.clear();
		}

		SaveData[i].Name = "";

		SaveFile.open("testing.txt", std::ios::in | std::ios::binary); 
		if (SaveFile.is_open()) {
			std::streamsize filenamesize;
			SaveFile.read(reinterpret_cast<char*>(&filenamesize), sizeof(std::streamsize));
			SaveFile.read(reinterpret_cast<char*>(&SaveData[i].Name), filenamesize);
			SaveFile.close();
			SaveFile.clear();
		}
	}

	return 0;
}


Setting a breakpoint on the return and viewing SaveData shows it read and wrote correctly.

Providing more context is difficult because the program is huge.

I'll try writing a different method in the meantime.
You can't write() and read() a std::string.

When writing a string you will need to write both the size of the string and the string.c_str().

When reading you will need to first read the size (written above) then resize the string to the required size before trying to read() the string. If you try to read() into an empty string your program will usually crash.

You haven't actually checked if your input is correct. I tested it and printed the output and it returned nothing (failed).

The main problem with the code (as jlb has stated) is your belief that string is like a cstring, and sizeof of a string is like a class with a vector inside of it (AKA a vector is just a pointer like a array allocated with new).
Last edited on
Topic archived. No new replies allowed.