Advertisement

Debug assertion failure? (c++)

Started by July 05, 2017 10:14 AM
21 comments, last by suliman 7 years, 4 months ago

You're overthinking it. If you get a problem when you delete a pointer then either:

a) the pointer was not valid at all, so you simply can't delete it

b) something the object owns isn't valid, so it breaks in the destructor

Without seeing the other code it's impossible to know what is going on. Most likely it's (b), and you probably have some completely unrelated operation which is trashing memory after the end of an army object. Double-check all your array and pointer operations.

Ive narrowed it down but im still stuck. It's these sections below that causes the debug assertion failure. It triggers when i try to clear the list after it has been populated with armies from disk.

Save armies to disk


		saveNum(armyList);
		loop2(army, armyList)
			fileSave(uu);
		endLoop

Load armies from disk


		loadNum
		for (int ii = 0; ii < num; ii++){
			armyList.push_back(army());
			army * uu = &armyList.back();
			fileLoad(theNewArmy);
		}

Defines used in these sections (these work fine in many other places so i dont think the problem is here):


#define saveNum(myList) num = myList.size(); fwrite( &num, sizeof(num), 1, f);
#define loadNum fread( &num, sizeof(num),1,f);

#define fileSave2(item) fwrite(&item.startSave,1,&item.endSave-&item.startSave,f);
#define fileLoad2(item)  fread( &item.startSave, 1,&item.endSave-&item.startSave, f);

#define loop2(classType,myList)										\
	{std::list<classType>::iterator it;								\
	for ( it = myList.begin(); it != myList.end(); ++it ){			\
		classType * uu=&(*it);

I'm aware that these save/load defines are not safe (will indead crash) when I change the content of the class saved, but thats fine for now.

Advertisement

I'm trying hard not to comment on the define usage :)

Are the members of army between endSave and startSave all PODs? 

PODs are "plain old data", that is, simple types that allow a continuous memory block being accessed like that. No STL containers or complex classes.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

They do contain custom classes but those contain only PODS (chars, int etc). Could it be the problem? I have around 40 members between startSave and endSave (so saving and loading each one manually is not a good idea...) and this has worked fine until i updated from visual studio 2008 to 2013. Could it be that the old version didnt care about the potential problems of this method?

If it's PODs all the way down this should be fine. You could however have some weird padding bytes in between. Do you read files written by 2008 in 2013? Make sure the struct/class padding has the same value then!

 

The CRT debug helpers may help you (https://msdn.microsoft.com/en-us/library/974tc9t1.aspx#BKMK_Find_buffer_overruns_with_debug_heap)

_CrtCheckMemory might help you locate the problematic piece of code by calling it at relevant locations.

If nothing else helps try narrowing the problem down. Comment out bigger blocks of code to see if you can isolate the cause, Just beware though: Memory corruption has the habit to stay hidden in certain circumstances (means, by uncommenting you could think you solved the problem while it is merely not directly visible)

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

ive deleted old files so im not mixing 2008 and 2013 versions at all.

On another note; how would you save/load such structures of game objects as armies, towns, units etc. Each one litteraly has up to 60-70 members containing data about them. I cannot manually save/load each member right? This "section"-save/load is sketchy i know, but up until now i havent had any problem with it.

Advertisement

I usually do save each member manually. I'm using binary methods in chunks, so I can add data later and still load older formats. However it is annoying :)

 

There are serializing libraries out there that can help you; in the end it boils down to tackle each member separately.

 

Still if it's only PODs your method should be fine.

 

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

I finally found it! Thanks for your help guys!

Simple custom classes (that include only PODs even if its in many layers) can be saved/loaded fine with my "load/save-section" defines. The problem is a single member:


std::vector<void*> path;

that I use for pathfinding. If i move that one out of the save/load range it works fine.

So it's because it's not a POD? I already handle this one manually after a load but anyway to avoid the debug assertion failure? My point is it's easiler to save that class in it's entierty and then deal with the few unique members that isn't safely saved/loaded.

Ouch... that's some really bad code, sorry to say. No wonder you hit bugs like this. There's no good reason to have a vector of void*.

No, an std::vector is not a plain old data type. It contains a pointer to a dynamically allocated array somewhere.

You shouldn't really be using fread and fwrite on complex objects like that. It's all very well you saying "it works fine" but this whole thread is an example of where that approach has made completely unrelated code crash. Unless you are completely confident about the content of every class, and sure they are all POD objects, and ideally also sure about the exact alignment and padding of those objects, and also sure that you have some sort of version or size check to make sure they can't accidentally load the wrong types, then you should not be doing this.

I wasn't aware of the issue until now and now I know what members that need special handling :) (manual save/load).

If there is a good alternative I would go for it, but right now, saving and loading each member manually is simply a "no go" for me (I would have to remake both save and load functions each time I add or change a member to any of the classes that needs to be saved/loaded to disk, which is basically all the time). And those save/load functions would be monsters to begin with (my town class has 87 members at the moment, all of them PODS).

 

This topic is closed to new replies.

Advertisement