Help with violating writing location

Hi! I'm using HGE for my program and I've stumbled upon a Access violation, the following is displayed in my output:

'2dlandzD.exe' (Win32): Loaded 'C:\WINDOWS\SysWOW64\avrt.dll'. Cannot find or open the PDB file.
First-chance exception at 0x52ADAD84 (msvcp100d.dll) in 2dlandzD.exe: 0xC0000005: Access violation writing location 0x00FFFFFF.

The program '[4120] 2dlandzD.exe' has exited with code 0 (0x0).

Here is the code of what it should regard:

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
void LevelEditorUnitHandler::loadUnits(string path, string fileName)
{
	BinaryHandler bHandler;
	BinaryUnit bUnit;

	ifstream load(path + "units.txt", ios::binary);
	if (load.good())
	{
		if (initialized)
		{
			clearUnits();
			load.read((char*)&bHandler, sizeof(BinaryHandler));

			nrOfUnits = bHandler.units;

			for (int i = 0; i < bHandler.units; i++)
			{
				load.read((char*)&bUnit, sizeof(BinaryUnit));
				units[i] = new LevelEditorUnit(loadSprite(bUnit.unitName),
					bUnit.x, bUnit.y, bUnit.unitName, bUnit.ownedBy, 453454);
			}
		}
		load.close();
	}
} < Giving me error here which is "next statement after returning from current function"


This is the initialize function who should be initializing everything necessary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void LevelEditorUnitHandler::initialize()
{
	if (!initialized)
	{
		nrOfUnits = 0;

		unitListSize = 5;
		unitList = new LevelEditorUnit * [unitListSize];
		unitTextures = new HTEXTURE[unitListSize];
		unitTextureNames = new string[unitListSize];
		loadUnitList();
		initialized = true;
	}
}


Here are the functions who is called inside the loadUnits():

1
2
3
4
5
6
7
8
9
10
void LevelEditorUnitHandler::clearUnits()
{
	for (int i = 0; i < nrOfUnits; i++)
	{
		delete units[i];
		units[i] = nullptr;
	}

	nrOfUnits = 0;
}


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
hgeSprite * LevelEditorUnitHandler::loadSprite(string unitName)
{
	string path = "../workingDir/data/units/" + unitName + "/";
	ifstream load(path + "animations.txt");
	if (load.good())
	{
		string scrap = "";
		load >> scrap;
		float w = 0, h = 0;
		load >> w;
		load >> h;
		for (int i = 0; i < texturesLoaded; i++)
		{
			if (unitTextureNames[i] == unitName)
			{
				cout << "Found existing texture" << endl;
				load.close();
				return new hgeSprite(unitTextures[i], 0, 0, w, h);
			}
		}

		cout << "Loading new texture" << endl;
		string loadFile = path + "texture.png";
		unitTextures[texturesLoaded] = hge->Texture_Load(loadFile.c_str());
		unitTextureNames[texturesLoaded] = unitName;
		texturesLoaded++;

		load.close();
		return new hgeSprite(unitTextures[texturesLoaded - 1], 0, 0, w, h);
	}
	else
	{
		load.close();
		return nullptr;
	}
}


I appriciate any help you can give me!
Sounds like either you overflowed a buffer or a destructor is giving you grief. Does BinaryUnit or BinaryHandler have non-trivial destructors?
You might want to take a look at the disassembly and see which call is failing.
They did not have any destructors at all. But since you named it i added it, both a contructor and a destructor.

I do not really know what you mean with non-trivial destructors, but I'll post you the code I added:

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
		class BinaryHandler
		{
			public:
				BinaryHandler()
				{
					units = 0;
				}
				int units;
		};
		class BinaryUnit
		{
			public:
				BinaryUnit()
				{
					unitName = "";
					x = 0;
					y = 0;
					ownedBy = 0;
				}
				~BinaryUnit()
				{

				} < this is instead the next statement to be executed
				string unitName;
				float x;
				float y;
				int ownedBy;
		};


These classes are located inside my "LevelEditorUnitHandler.h" and not the .cpp file.

Since I added destructors the error directed me to a different location which is pointed out in the above code.

EDIT: Now I got a reading violation instead of writing, this is driving me insane...

Thanks for helping!
Last edited on
There it is. You can't pass a pointer to a BinaryUnit to istream::read(), it's a non-POD type because of BinaryUnit::unitName.
See http://en.wikipedia.org/wiki/Plain_old_data_structure
Ahh I get it now, but how would I resolve this? I believe you are not able to store strings in binary? So should i change this string into a char* since chars could easily be read?
should i change this string into a char* since chars could easily be read?
Do you want to write the characters of the string, or a pointer to the string?

You'll have to do the de/serialization yourself. Your code will end up looking somewhat like this:
1
2
3
4
5
size = read_32_bits(file);
unitName = read_string(file, size);
x = read_float(file);
y = read_float(file);
ownedBy = read_32_bits(file);

Alternatives: If you just want to save some data from your program and don't need to support an existing format, you can look at Google's Protobuf. It's a basically a compiler from a data specification language to C++ that generates a class with all the de/serialization stuff. The data specification looks somewhat like this:
1
2
3
4
5
6
message BinaryUnit{
    required unitName = 1;
    required float x = 2;
    required float y = 3;
    required int ownedBy = 4;
};
I'll look into Google's Protobuf!

Thank you very much for your help :)
Topic archived. No new replies allowed.