Archived

This topic is now archived and is closed to further replies.

PumpkinPieman

Unexpected crash

Recommended Posts

Alright, I have no clue what causes this, but is there someone who can tell me what''s going wrong.
Unhandled exception at 0x00427c6b in Twilight.exe: 0xC0000005: Access violation reading location 0xabababab. 
int main()
{
	CPlayer NewPlayer;
	delete NewPlayer.m_PlayerBelt; //Pointer to CBelt
	delete NewPlayer.m_PlayerBag; //Pointer to CBag, which uses std::multimap as a base class
	std::cout << sizeof(NewPlayer);
	return 0;
}; // Error occurs here.
The violation occurs at (Refined)
	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (_TREE_ITERATOR(_Lmost()));
		}

Share this post


Link to post
Share on other sites
What''s your constructor/destructor look like? You''re deleting something that we don''t know how got constructed, then you aren''t setting it to NULL so you''re probably accessing it in the destructor. Too little information with too many things it could be.

Just as an aside. With classes, you should make your members private, and only free them from within the class. And always, always, always set pointers to NULL when you free them.

Share this post


Link to post
Share on other sites
What does your CPlayer class look like? If m_PlayerBelt and m_PlayerBag are defined as pointers, then immediately calling delete on them after CPlayer is instanced is a bad idea, as they have not yet been allocated. If they are not pointers, then calling delete on them again is a bad idea. At any rate, deleting individual members of a class is bad form; that should be handled within the class, transparent to the user of the class.

EDIT: Heh. Too slow, Chozo beat me to it.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

[edited by - VertexNormal on November 14, 2003 2:19:47 PM]

Share this post


Link to post
Share on other sites

CPlayer::CPlayer(void)
: m_modHP(1.0)
, m_modChi(1.0)
, m_modWei(1.0)
{
m_PlayerBelt = new Belt;
m_PlayerBag = new CBag<int, CItem*>;
}

CPlayer::CPlayer(double m_pmodHP, double m_pmodChi, double m_pmodWei)
: m_modHP(m_pmodHP)
, m_modChi(m_pmodChi)
, m_modWei(m_pmodWei)
{
m_PlayerBelt = new Belt;
m_PlayerBag = new CBag<int, CItem*>;
}
CPlayer::~CPlayer(void)
{
if(m_PlayerBelt)
delete m_PlayerBelt;
if(m_PlayerBag)
delete m_PlayerBag;
}

That''s the deconstructor of the CPlayer Class. I want to beable to delete those two pointers eventually.

Share this post


Link to post
Share on other sites
Aha. If you delete those two pointers in your main() function but do not then set them to 0, they are deleted again when the program exits and the CPlayer destructor is called on NewPlayer. In main(), after you delete the pointers, set them to 0 and the crash should be fixed.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

Share this post


Link to post
Share on other sites

-----------------------------------------------------------
To expand on what VertexNormal said:

You should (usually) try to put all the classes resource management inside the class. First you should make sure that the constructor of CPlayer either new's the pointers, or sets them to NULL/0 explicitly. The destructor of CPlayer should then be responsible for deleting them.
If you're trying to go for OO, you should probably make the pointers private, and provide getter methods. This way a user of your class can't accidently delete resources of your class.
-----------------------------------------------------------


Edit: Wrote my reply before your answer. Looks like you're already doing this. Like VertexNormal said, you're deleting the pointers twice. This is a good examply why pointers inside the class should be private. That would've prevented that mistake.

Also, the "if(pointer) delete pointer"-construction, is unnecessary 'delete' already takes that case into account.

[edited by - Wildfire on November 14, 2003 2:38:37 PM]

Share this post


Link to post
Share on other sites
It looks like you''re deleting each member variable twice... once in your main and another time in your destructor once main goes out of scope. As mentioned before, in your destructor set your variables to NULL once you delete them.





--{You fight like a dairy farmer!}

Share this post


Link to post
Share on other sites
quote:
Original post by sagwagon
quote:

For Beginners - Unexpected crash



BWAHAHAHAHAHAHAHAHA

It's nice to see the topic amuses you, but unless you have anything constructive to say; then don't bother saying it.


[edited by - PumpkinPieman on November 14, 2003 8:10:52 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by PumpkinPieman
Unhandled exception at 0x00427c6b in Twilight.exe: 0xC0000005: Access violation reading location 0xabababab.  



Something to keep in mind: when built in debug mode the compiler fills memory with certain values so you can better see what happens when stepping though. Codes like 0xcccccccc and 0xcdcdcdcd are used by Visual Studio to mark uninitialised memory, deleted memory and such (can''t remember the exact usage, sorry).

I''ve not seen the 0xabababab one before, what compiler is it? Looking though its docs should tell you what this particular code means.

Share this post


Link to post
Share on other sites
Also, I tried making an operator that overloads delete.

void operator delete(void *pUserData)
{
delete pUserData;
pUserData = NULL;
};

I don''t know, it seems to work though debug, but when it returns the variable that''s passed is unchanged, although it clearly is set to null within the function.

Share this post


Link to post
Share on other sites
quote:
Original post by PumpkinPieman
Also, I tried making an operator that overloads delete.

void operator delete(void *pUserData)
{
delete pUserData;
pUserData = NULL;
};

I don''t know, it seems to work though debug, but when it returns the variable that''s passed is unchanged, although it clearly is set to null within the function.


It''s because the pUserData variable given to delete() is a copy (passed by value) of the variable passed. You are setting this local copy to NULL, but that local copy merely gets thrown out when it goes out of scope (the delete() function ends); meanwhile, the original is unchanged. Classic case of "pass by value vs. pass by reference confusion".

Trying to overload delete in this fashion is really unnecessary anyway. Just make a habit of setting to NULL every time you delete something; it''s a good habit to get into.

Josh
vertexnormal AT linuxmail DOT org


Check out Golem: Lands of Shadow, an isometrically rendered hack-and-slash inspired equally by Nethack and Diablo.

Share this post


Link to post
Share on other sites