Advertisement

delete error

Started by March 21, 2000 12:06 AM
7 comments, last by chippydip 24 years, 7 months ago
Ok, I''ve been working on this one for at least an hour... Logging function calls, debugger, etc. but no luck Here''s what I''ve found so far, does anybody have any ideas? I have 3 game classes right now, plus some basic windows stuff (WinMain, WinProc) and an error logging class. I''ve managed to narrow the origin of the problem to my ~CErrorLog() funtion b/c I can get the program to run fine if I comment out all the ''delete error'' calls, but this is poor style, so I''d like to avoid it... The CErrorLog class has 2 static variables (a refCount of the number of CErrorLog objects, and a file pointer which is shared by all CErrorLog objects) it also contains a char* with a unique text identifier for each object. Here is the class declaration:

class CErrorLog
{
public:

	// Creation and deletion

	CErrorLog (const char* name = "Unknown");
	~CErrorLog ();

	// Interface

	void Track (const char* msg, ...);
	void Log (const char* msg, ...);
	void Kill (const char* msg, ...);

private:

	char* nameID;

	static FILE* fp;
	static int refCount;
};
And here are the implementations of the creation and deletion function:

FILE* CErrorLog::fp = NULL;
int CErrorLog::refCount = 0;

#define FORCEFLUSH

// ## FUNCTIONS ################################################################
// =============================================================================
//	Function:	CErrorLog
//	Purpose:	Increase the reference count and open the error file in needed.
// =============================================================================

CErrorLog::CErrorLog (const char* name)
: nameID(NULL)
{
	// Update the number of references

	++refCount;

	// If the file is not open, open it

	if (!fp)
	{
		// Open the error file. If its not for the first time we should append
		// to whatever data is already in there. (I wonder why it closed?)

		if (refCount != 1)
			fp = fopen("ErrorLog.txt", "a");
		else
			fp = fopen("ErrorLog.txt", "w");

		// If the file is still not open, then don''t bother to continue.

		if (!fp)
			exit(10);

		// Make sure the file output is showing up.

		fprintf(fp, "+--------------------+\n");
		fprintf(fp, "/ Error file opened  /\n");
		fprintf(fp, "+--------------------+\n");
	}

	// Set the nameID of this inststance.

	char buffer[255];
	sprintf(buffer, "%s\t(%d): ", name, refCount);

	nameID = new char(strlen(buffer) + 1);
	strcpy(nameID, buffer);

	Track("ErrorLog created: (%s\t%d)", name, refCount);
}

// =============================================================================
//	Function:	~CErrorLog
//	Purpose:	Decrease the reference count and close the file if its zero.
// =============================================================================
	
CErrorLog::~CErrorLog ()
{
	--refCount;

	Track("ErrorLog closed: (%s\t%d)", nameID, refCount);

	if (refCount == 0)
	{
		Track("Closing file.");
		fprintf(fp, "+--------------------+\n");
		fprintf(fp, "/ Closing error file /\n");
		fprintf(fp, "+--------------------+\n");

		fclose(fp);
	}

	delete nameID;

}
With the ''delete error'' calls in, the program crahes while executing the ''delete nameID;'' line above with the error: DAMAGE: after Normal block (#55) at 0x007B1DF0. And then another message: Break point reached (or something to that effect) and when I enter the debugger, the call stack is: _free_dbg(void*, int) operator delete (void*) CErrorLog::~CErrorLog() CErrorLog::''scalar deleting destructor'' (unsingned int) (..more of my call stack here...) And with that line commented out, it still terminates as follows: The instruction at "0x004a871" referenced memory at "0x007afdc2". The memory could not be "written". And the call stack is: __sbh_free_block(tagHeader*, void*) _free_base(void*) _free_dbg(void*, int) operator delete (void*) CErrorLog::''scalar deleting destructor'' (unsingned int) (..more of my call stack here...) Any ideas about what''s going on? I''m I messing up the static variables? Is MSVC++ messing up the static variables? Those are the only things I can think or right now... If you have any other ideas, please let me know and I''ll check them out...
Ok, after writing that last post, I decided to change my static variables into globals to see if that was causing the problem, but it doesn''t seem to have any effect on the errors... back to the drawing board I gues... I hope someone else has more luck figuring this out than I have had so far
Advertisement
I might not be on the right track here, but I believe that nameID is an array of chars? In that case, you need to use delete[] instead of the regular delete. Whenever you allocate an array in C++ using new, you have to use delete[] to free it.

I hope that solves your problem!
One thought is trying to replace the name id field with a STL string or stringstream object. That way the deletion of the object will be implicit rather than explicit. Note: not a pointer to a string or stringstream, but actually allocated in the object. Or replace it with a fixed buffer of 255 chars. Either way it will test if deletion of your name id is really the culprit.
Ok, I believe that new char() is used for a pointer to a single item, and I think that''s screwing up what you''re trying to do, I think what you''re trying to do is new char[strlen(buffer)+1] and then delete []nameID; I''m pretty sure this''ll work because I was messing around with similar code and it worked for me...but I''m using a different compiler, well enough chat, I hope this helps, sorry if it doesn''t =)
Chris
Doh!

jaxon and BraveZeus: right on... arrays work much better if you declare them as arrays and delete them as such

SiCrane: I''ve been interested in using STL classes/function from time to time, but I can never get then to work right under MSVC++ Do you know of any good tutorials/examples of how to set up the includes and deal with the namespace stuff? I always seem to end up with name clashes when I try to say ''using namespace std;'' or whatever

Oh, well... its working now! Thanks for all the help and man do I feel dumb for missing that! Too many hours staring at code I guess

Advertisement
I only use STL in Borland C++ Builder and g++. In both those, just typing #include <sstream> up top seems to work just fine. I believe in version 0.3 or 0.4 ClanLib switched over to STL, so you can browse the source to that as a reasonably complex set of example code that compiles in Visual C++.
I use STL in MSVC like so:

typedef std::list<SomeType> SomeTypeList;

You can then declare objects of type SomeTypeList, and use SomeTypeList::iterator to go through them. Since you only take as much from the namespace as you need, there should be less collisions, and it cleans up your code by removing all those spare brackets and colons

Edited by - Kylotan on 3/21/00 5:24:48 AM
Kylotan: Thanks for the idea, I''ll have to try that at some point

This topic is closed to new replies.

Advertisement