Skip to main content
gamedev.net
🔒 Locked

Deconstructors problem

Started by Anima Jul 13, 2004 at 8:51 AM 5 replies 950+ views
Original Post
Anima
Anima
I've been having problems with a program and eventually found the source of the problem which is demonstrated by the following code:

#include <list>
#include <iostream>

class cString
{
public:
	cString (){ str = 0; }
	virtual ~cString ()	{ if (str != 0) delete [] str; }
	char* str;
};

int main ()
{
	std::list <cString> List;

	cString string;
	string.str = new char [32];
	List.push_back (string);

	return 0;
}

Running this will cause the program to crash because the deconstructor is called twice, once when the cString object is destroyed and again when the list is destroyed. Although I can see the cause of the problem I've been having a hard time trying to find a solution to it. The following code is from my actual project:

{
	// ...
	cARC_FileInfo newFile;

	newFile.SetName (strName);
	newFile.SetFilePath (strFilePath);
	newFile.SetLength (0);
	newFile.SetOffset (0);

	m_FileTable.push_back (newFile);

	return true;
}

As you can see, the code creates a temporary object, sets the properties (including memory allocation in SetName), and then appends this to the m_FileTable list. However, when the function end is reached, the temporary object is destroyed, which destroys the string which the object in the list is still pointing to. What is the best way to avoid this problem?
SiCrane
SiCrane
You need to implement a copy constructor for your class. The way you have things laid out, the copy constructor should allocate new memory for the held char array and copy the array contents.
dmikesell
dmikesell
Or use std::string...
hplus0603
hplus0603
The rules-of-thumb for object construction are:

If you have a destructor, then you should also have a copy constructor, and an assignment operator.

If you have a virtual function, then the destructor should also be virtual.

Your object should have a default constructor.


In your copy constructor and assignment operator, you can choose to allocate a new string block and copy the contents, or to copy the pointer, but keep a reference count in the pointed-at data. You can, for obvious reasons, not keep the reference count in the object itself.

Or, as someone else already said: use std::string. It solved these problems already.
enum Bool { True, False, FileNotFound };
Etnu
Etnu
I've said it before, and I'll say it again: If you're already using STL classes for one thing, you might as well use them for another, especially since doing a custom string implementation using std::list will be much slower than just using std::string (or std::basic_string or std::wstring)
---------------------------Hello, and Welcome to some arbitrary temporal location in the space-time continuum.
Anima
Anima
*smacks self in face* I should've known that... Thanks, all.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.