Re: Document corrupted after showing dialog
On Wed, 16 Jul 2008 03:19:38 +0200, WP <invalid@invalid.invalid> wrote:
Hello group!
I'm having the weirdest error in a simple game I'm making (tile-based
game where the player must guide a character out of a maze).
When the player locates the exit in the maze and the score was good
enough to break into the hiscore list a dialog box is displayed asking
for the player's name. I had a very weird problem after showing that
dialog: memory seemed corrupted. I was preparing a long post trying to
explain it when I stumbled on the error: Here's the OnInitDialog in my
dialog that asks for a name:
BOOL
NameDialog::OnInitDialog()
{
CDialog::OnInitDialog();
//swprintf_s(message, sizeof(message), _T("You broke into the
hiscores list with %u steps."), num_steps);
name_edit.SetFocus();
return FALSE;
}
Notice the commented-out line? It create a message string that's
supposed to be drawn in OnPaint() (which works, btw, and by works I mean
that it's displayed correctly).
The variable message is: TCHAR message[256]. num_steps is of type
unsigned int. If that line is not commented out, memory gets corrupted
when the dialog object goes out of scope (no memory corruption if I make
the dialog object static). Why? What's wrong with it? Hope I made some
sense...I think I can work around it, but I'm curious why this happens.
It doesn't make sense to use the T macros and types with wide character
functions like swprintf_s. As Joe mentioned, you are passing the array size
as bytes, when it should be the number of characters it can hold. But if
message is really 256 wchar_t's long, your message string cannot overflow
it. So it seems to me this is just a weird coincidence that commenting the
line out avoids the crash, unless swprintf_s fills the buffer to the
specified size, which would be strange. Since you aren't declaring message
locally (And why not?), I presume you're using it elsewhere, and perhaps
you're making an unwarranted assumption about its contents in one of those
places, such that the behavior is different when the swprintf_s call is
made and when it isn't. These are the sorts of thing you need to consider
when you face a problem like this, but as Joe said, you'd be better off
scrapping this approach and using CString::Format, which is not subject to
these problems.
--
Doug Harrison
Visual C++ MVP