Archived

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

LizardAl

What's up with this?

Recommended Posts

Howdy I''ve come across a bizarre problem (or at least I think it is) . I have the following code in my WinMain function:
  
while (1)
{
	if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
	{
		if (msg.message == WM_QUIT)
		{
			break;
		}
		else
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
	else
	{
		if (CConsole::GetInstance().NeedToDraw())
		{
			CConsole::GetInstance().Draw();
		}
		CScreen::GetInstance().Flip();
	}
}
  
Looks alright to me, but when I run it, my computer freezes. The weird thing is, when I debug it, either using step into or step over, it works perfectly fine! However, to further complicate things...The CScreen::Flip() method returns a bool, which I have as a typdef''d int (i''m using VC++ 4.0, so there''s no built-in support). When I step into the method, and step all the way through it, it returns 1 (true) as expected, but when I step over it, it returns four hundred thousand and some. What''s up with that? Also, my CConsole class...when I step into the Draw function, the this pointer is pointing to four bytes after the actual start of the console object. What I mean is &CScreen::m_instance will be something like 0x00421358 and the this pointer inside the method will be 0x0042135c! None of my other singleton objects do this, and I suspect it has something to do with the CConsole class'' multiple inheritance. Anyway, sorry this is so long, but if anybody knows what could be causing any of these things, please let me know! Thanks, Scott

Share this post


Link to post
Share on other sites
Sounds like a problem in your CConsole or CScreen class. Comment out each class related calls and see how it reacts. Without code for those classes I can''t really say more ...

Share this post


Link to post
Share on other sites
I tried commenting out both CScreen::Flip and CCanvas::Draw and it works fine, but with either of them uncommented it doesn''t work.
Code snippets...
in CConsole:
  
inline bool NeedToDraw() { return m_active; }

bool Draw()
{
m_canvas->Fill(m_backColor);

uint32 fontSize = m_size / (CONSOLE_MAXLINES + 6);

for (uint32 str = 0; str < CONSOLE_MAXLINES; str++)
{
if (*m_text[str] != (const char*)"")
{
if (!m_canvas->DrawText(10, str * fontSize + 3, m_text[str], m_font))
{

return false;
}
}
}

return m_canvas->Blt(0, 0);
}

The m_canvas is just a pointer to my DirectDrawSurface wrapper, which I''ve tested throroughly. I''m nearly positive there are no problems there.

and in CScreen:
  
bool CScreen::Flip()
{
// If we''re in fullscreen mode, we can actually page

// flip the surfaces (swap pointers).

if (m_fullscreen == true)
{
return SUCCEEDED(m_primary->Flip(0, DDFLIP_NOVSYNC));
}

else
{
// In windowed mode, we have to blt the buffer to

// the primary surface.

uint32 x = CDisplay::GetInstance().XOffset();
uint32 y = CDisplay::GetInstance().YOffset();

RECT destRect = {x, y, x + m_width, y + m_height};

return SUCCEEDED(m_primary->Blt(&destRect, m_surface, 0, 0, 0));
}
}


This is where the main problem is, I think, but I honestly can''t see anything wrong with it...

Thanks,
Scott

Share this post


Link to post
Share on other sites
I don't think there's any problem with the expression *m_text[str] (assuming m_text is an array of string pointers like it appears to be, and that you're trying to retrieve the first character of a given string), since the subscript operator should have precedence over the deference operator. It wouldn't hurt to throw in a couple of parentheses just to be safe, though. Also make sure that each string is allocated and terminated properly (forgetting that null char can send your computer into la la land real fast under certain circumstances).

However, I'm confused as to why you're comparing it to the expression (const char *)"", which of course resolves to the memory address of a 1-byte static string. The only way I can see this working is if m_text points to a special string class with several operators overloaded (can't compare string contents directly using default operators in C/C++, as I'm sure you know). But if that's the case then why the dereferencing in the *m_text[str] expression? As Gorg said, you need to post the declaration code for this variable.

Even if the problem isn't in your m_text array, the symptoms do sound like those caused by a memory violation. Read/write to the wrong location and a debugger can return some interesting yet worthless information, throwing you off track for days. My current record is some 30 hours (spread over a month) of traditional debugging (no debugger) in order to find one little dereferencing mistake. =)

EDIT: Heh, took me so long to compose this that I didn't see your m_text explanation. If it's an array of pointers to instances of your class, like you said, then that makes sense. I was thinking it might be a pointer to an array of instances (one contiguous memory block), which would be bad. ^_^

Edited by - Ramius on April 22, 2001 12:08:15 PM

Share this post


Link to post
Share on other sites
You have one choice then :

#1 Comment out body of the two fonctions.

#2 For Draw
uncommentoneline
rebuild/test
do until all lines are uncommented or faulty line is found

#3
if issue is not found after #2, execute #2 for flip.




Sorry for the weird algo, I just wanted to write it quickly.



Edited by - Gorg on April 22, 2001 5:11:10 PM

Share this post


Link to post
Share on other sites
What does
  
if (*m_text[str] != (const char*)"")

get you?

If you are declaring an array of string then you basically have;
  
char* m_text[CONSOLE_MAXLINES];

// initialize to NULL

for(int i=0; i<CONSOLE_MAXLINES; i++)
m_text[i] = NULL;


which you would allocate for a given string as;
  
// make sure to delete existing string if any

if (m_text[STRING_INDEX] != NULL) delete[] m_text[STRING_INDEX];
// allocate memory for string plus the NULL character

m_text[STRING_INDEX] = new char[sizeof(string) + 1];


For these you will do comparison as follows;
  
// check for NULL string

if (m_text[STRING_INDEX] != NULL)

// string comparison

if (strcmp(m_text[STRING_INDEX], string) != 0)

// or if you know the string length

if (strncmp(m_text[STRING_INDEX], string, MAX_LENGTH) != 0)


Share this post


Link to post
Share on other sites
I have m_text defined in CConsole as:
string* m_text[CONSOLE_MAXLINES];

I have overloaded the != operator to test for inequality between a string and a character array. So, *m_text[str] != (const char*)"" sends a string object and a character array to the overload operator function. This works fine, I''ve tested it. And in my actual code I have everything inside that for loop commented out anyway because my font classes aren''t implemented, so I know the problem can''t be there anyway.

However, I have made a discovery (log files are your friend! )...The computer doesn''t freeze, it just responds extremely slowly. My Flip function and Draw function get called constantly, and they always return success, it just takes an extremely long time for Windows to realize that I''ve pressed a key. Anybody know why this could be?

Thanks again,
Scott

Share this post


Link to post
Share on other sites
First and foremost your program is constantly looping without any type of timer/sleep function. This causes everything to loop so fast that your input gets buffered, and your computer slows down to what appears to be an extremly slow frame rate. In all reality your processing to fast.

And on another not the ELSE is completely not nessassary. If your program makes it to Translate & Dispatch then WM_QUIT is false because otherwise it would''ve broken out of the loop.

Now what''s up with the second else? You should constantly be checking the windows messages even if game processing is going on. This will allow you to get both keyboard & mouse input. So I''d get rid of that else statement also.

That should solve the problems.

Share this post


Link to post
Share on other sites