What's up with this?

Started by
8 comments, last by LizardAl 23 years ago
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
Advertisement
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 ...
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
*m_text[str]


This looks weird to me. How is this array declared??
Sorry, m_text is an array of pointers to my own string class, I forgot to mention that...
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
- Daniel Roth, Programmer / Web Developer (www.starquail.com, www.cwu.edu)
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
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 NULLfor(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 anyif (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 stringif (m_text[STRING_INDEX] != NULL)// string comparisonif (strcmp(m_text[STRING_INDEX], string) != 0)// or if you know the string lengthif (strncmp(m_text[STRING_INDEX], string, MAX_LENGTH) != 0)  


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
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.
Joseph FernaldSoftware EngineerRed Storm Entertainment.------------------------The opinions expressed are that of the person postingand not that of Red Storm Entertainment.

This topic is closed to new replies.

Advertisement