Archived

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

My font class on destructor/clean up crashes on certain thing...

This topic is 5149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

ive made a font class
class Font {
public:
	LPD3DXFONT lp_Font;
	Font(char font[], int size, int weight,bool underline, bool italic)
	{
		HDC hDC= GetDC( NULL );
		int nHeight= -( MulDiv( size, GetDeviceCaps(hDC, LOGPIXELSY), 72 ) );
		ReleaseDC( NULL, hDC );					
		HFONT hFont = CreateFont(nHeight, 0, 0, 0, weight, italic, underline, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, font );
		D3DXCreateFont(lp_Device , hFont, &lp_Font);
		DeleteObject( hFont );	
	}
	
	~Font()
	{
		if (lp_Font!=NULL)
			 lp_Font->Release();
	}
};
I am using it in a function, this is where i believe the error maybe. When i start my program depending on the number of instances that i manually call the font class eg. call it once it crashes only when i close the program, and when i call it more than once it crashes at the start. By crashes i mean "unhandled exception, access violation" i call the font class through a method which is:
vector <Font> myFont;
void set(char font[], int size, int weight,bool underline, bool italic)
{	
  myFont.push_back(Font(font,size,weight,underline,italic));
}
i think its something to do with the calling of the Font in the method, but i have no idea why its doing this. Any ideas? Thanks,

Share this post


Link to post
Share on other sites
Your Font class is causing this problem. When you construct a Font object and pass it as a parameter in one step, the compiler creates a temporary Font object, then passes to push_back. Inside push_back, there should be some code similar to this:

m_StorageArray[index] = NewObject;

to add the object to its internal array. When the call to push_back returns, the temporary Font object is no longer needed, and gets destroyed. When that happens, lp_Font gets released in the destructor. However, one element in the vector (m_StorageArray[index] above) still has its lp_Font point to this released ID3DXFont object. When you access that Font instance, crash occurs.

The easiest solution is to define an assignment operator and write it like this:

Font &operator=( const Font &rhs )
{
if( &rhs == this ) return *this;
lp_Font = rhs.lp_Font;
((Font&)rhs).lp_Font = NULL;
return *this;
}

What this achieves is that once a Font object shows up on the right side of an assignment, it no longer references an ID3DXFont object (since another Font object now does). Consequently no more than one Font object can reference the same ID3DXFont object.


[edited by - jacklin on November 11, 2003 1:57:25 AM]

Share this post


Link to post
Share on other sites
ive decided to change the design of my program a bit.

eg
Font myFont;

int WinMain()
{
declareDxDeviceEtc;

myFont= Font("Arial",12, etc);
return 0;
}

but i get the same problem with the Font("arial... deleting itself while myFont is using it or something...

any ideas on this?

Thanks,

Share this post


Link to post
Share on other sites
Whether you use push_back or a direct assignment it''s still doing a bitwise copy, so it''s going to be a problem.

It doesn''t get much simpler than this:

Font *myFont;

int WinMain()
{
//Set stuff up
myFont= new Font("Arial",12, etc);

use_font_for_stuff;

//Now that you''re done with it
delete myFont;

return 0;
}



Stay Casual,

Ken
Drunken Hyena

Share this post


Link to post
Share on other sites
quote:
Original post by jacklin
You still have the same problem as the original design does. If you must use a class, define an assignment operator as I showed above.



jacklin thanks for your orginal reply, but i sorta intend on using that as a last resort , you see its quite complicated compared to my skill in c++


edit:

hmmm about using pointers, i just don't like the idea of having to delete it afterwards...

[edited by - johnnyBravo on November 12, 2003 2:58:29 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by johnnyBravo
hmmm about using pointers, i just don''t like the idea of having to delete it afterwards...


That''s basically what you''re doing when you allocate and release DirectX resources. And being able to dynamically allocate resources can be tremendously useful so it''s something worth getting used to. But if you really want to avoid it:

WinMain(){
//InitDX
Font myFont("Arial",12, etc);

Use_myFont(&myFont);


//When WinMain exits, it will be freed.
}

Share this post


Link to post
Share on other sites