Thread: Memory problem...?

  1. #1
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107

    Memory problem...?

    I've been trying to figure out this what's wrong with my program with little success, so I'm going to post what I've been experiencing to see if anyone can figure it out. Basically, when my program hit's a cetain amount of memory usage (aproximately 9-10 mb), the whole thing goes completly screwy. First of all, on the control I wrote which is the program's primary memory guzzler, whenever it tries to redraw itself it causes various parts of the screen to turn grey. Even parts it shouldn't be able to draw over like the start menu. On top of that, I keep getting error messages when using API funtions (just the ones that handle drawing) under circumstances where they worked perfect before the problem was triggered. But despite all this, the VC++ debugger reports absolutely nothing unusual. If anybody has had a similar problem while programming a windows app I'd like to know about it because I have absolutely no clue what's going on.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It looks like you're leaking GDI handles.

  3. #3
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Maybe... I'll post my draw routine so you can take a look at it
    Code:
    LRESULT DasmViewer_OnPaint(DASMVIEWERINFO * dvp, WPARAM wParam, LPARAM lParam)
    {
    
    	HDC          hdc;
    	HDC			 hdcTemp;
    	HBITMAP      hbmNew;
    	HBITMAP      hbmOld;
    	PAINTSTRUCT  ps;
    	HANDLE       hOldFont;
    	RECT         rect;
    	RECT         titleBarRect;
    	RECT         selectedRect;
    	UINT         offsetMod = 0;
    	char *       string;
    	int			 iRow;
    	int          iCol;
    	int          i;
    
    	//Get a device context for this window
    	if(wParam)
    		hdc = (HDC)wParam;
    	else
    		hdc = BeginPaint(dvp->hWnd, &ps);		
    
    	//Work out where to draw
    	GetClientRect(dvp->hWnd, &rect);
    
    	//Set up to draw to a temporary bitmap
    	hdcTemp = CreateCompatibleDC(hdc);
    
    	hbmNew = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
    
    	hbmOld = SelectObject(hdcTemp, hbmNew);
    
    	//Set the font
    	hOldFont = SelectObject(hdcTemp, dvp->hFont);
    
    	//Paint the background black
    	FillRect(hdcTemp, &rect, CreateSolidBrush(dvp->bgColor));
    
    	SetTextColor(hdcTemp, dvp->fgColor);
    
    	SetBkMode(hdcTemp, TRANSPARENT);
    
    	for(iCol = 0; iCol < dvp->collumns; iCol++)
    	{
    		DrawString(hdcTemp, rect, dvp->colTitles[iCol], dvp->colPstns[iCol], dvp->rowTopPad, NULL, -1);
    	}
    
    	dvp->tempOffset = dvp->offset;
    
    	if(dvp->tempFileInfo.hFile)
    	{
    
    		dvp->rowOffset[0] = dvp->offset;
    
    		//Calculate the offset for each row
    		for(iRow = 1; iRow <= dvp->rows; iRow++)  //Also Calculates one row ahead in order to set rowCurrentBytes
    			dvp->rowOffset[iRow] = dvp->rowOffset[iRow - 1] + dvp->fixedOpcodeBytes;
    
    		for(iRow = 0; iRow < dvp->rows && (dvp->tempOffset  < dvp->tempFileInfo.fileSizeLow || (!dvp->tempFileInfo.fileSizeLow && !iRow)); iRow++)
    		{
    			dvp->rowCurrentBytes = dvp->rowOffset[iRow + 1] - dvp->rowOffset[iRow];
    
    			for(iCol = 0; iCol < dvp->collumns; iCol++)
    			{
    				if(dvp->colPstns[iCol] > -1)
    				{
    					string = dvp->colTextFuncs[iCol](dvp);					
    
    					//Update charWidthArrays and charWidthArraysTotals as neccessary
    					if(dvp->colLongestLength[iCol] < (dvp->colCurrentLength[iCol] = (int) strlen(string)))
    					{
    						for(i = dvp->colLongestLength[iCol]; i < dvp->colCurrentLength[iCol]; i++)
    							dvp->charWidthArrays[iCol][i] = dvp->charWidth;
    
    						if(dvp->colDrawGroups[iCol])
    						{
    								for(i = dvp->colLongestLength[iCol] + (dvp->colLongestLength[iCol] % dvp->colDrawGroups[iCol]) + (dvp->colDrawGroups[iCol] - 1); i <= dvp->colCurrentLength[iCol]; i += dvp->colDrawGroups[iCol])
    									dvp->charWidthArrays[iCol][i] +=dvp->colGroupSpace[iCol];
    						}
    
    						if(dvp->colLongestLength[iCol] == 0)
    								dvp->charWidthTotals[iCol][0] = dvp->charWidthArrays[iCol][0];
    
    						for(i = dvp->colLongestLength[iCol] + !dvp->colLongestLength[iCol]; i < dvp->colCurrentLength[iCol]; i++)
    								dvp->charWidthTotals[iCol][i] = dvp->charWidthArrays[iCol][i] + dvp->charWidthTotals[iCol][i - 1];
    
    						dvp->colLongestLength[iCol] = dvp->colCurrentLength[iCol];
    
    					}
    
    					//Paint the highlighting
    					if(iCol == dvp->colEditable)
    						if(dvp->selectedAreaBeginIndex > dvp->tempOffset * dvp->colCharsPerByte[iCol] && dvp->selectedAreaEndIndex <= (dvp->tempOffset * dvp->colCharsPerByte[iCol]) + dvp->colCurrentLength[iCol])
    						{
    							selectedRect.top    = dvp->rowHeightTotals[iRow] + dvp->rowTopPad + 1;
    							selectedRect.bottom = dvp->rowHeightTotals[iRow] + dvp->rowHeight + dvp->rowTopPad;
    							selectedRect.left   = dvp->colPstns[iCol];
    							selectedRect.right  = dvp->colPstns[iCol] + dvp->charWidthTotals[iCol][dvp->colCurrentLength[iCol] - 1] - dvp->colGroupSpace[iCol] * !(dvp->colCurrentLength[iCol] % dvp->colDrawGroups[iCol]) + 3;
    							
    							if(dvp->selectedAreaBeginIndex - 1 > dvp->rowOffset[iRow] * dvp->colCharsPerByte[iCol])
    								selectedRect.left += dvp->charWidthTotals[iCol][dvp->selectedAreaBeginIndex - dvp->rowOffset[iRow] * dvp->colCharsPerByte[iCol] - 2];
    
    							if(dvp->selectedAreaEndIndex < dvp->rowOffset[iRow + 1] * dvp->colCharsPerByte[iCol])
    								selectedRect.right -= dvp->charWidthTotals[iCol][dvp->rowOffset[iRow + 1] * dvp->colCharsPerByte[iCol] - dvp->selectedAreaEndIndex - 1];
    
    							FillRect(hdcTemp, &selectedRect, CreateSolidBrush(dvp->slBgColor));
    						}
    
    					//Draw the text
    					DrawString(hdcTemp, rect, string, dvp->colPstns[iCol], (dvp->rowHeight * (iRow + 1)) + dvp->rowTopPad + (dvp->barWidth * 2), dvp->charWidthArrays[iCol], -1);
    
    					free((void *) string);
    				}
    			}
    
    			dvp->tempOffset += dvp->rowCurrentBytes;
    		}
    	}
    	SetBkColor(hdcTemp, dvp->bgColor);
    
    	//Paint a bar under the title row
    	titleBarRect = rect;
    
    	titleBarRect.top = dvp->rowHeight + dvp->rowTopPad;
    	titleBarRect.bottom = dvp->rowHeight + dvp->rowTopPad + dvp->barWidth;
    
    	FillRect(hdcTemp, &titleBarRect, CreateSolidBrush(dvp->fgColor));
    
    	//Update the control's display
    	BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, hdcTemp, 0, 0, SRCCOPY);
    
    	//Release paint objects
    	SelectObject(hdcTemp, hbmOld);
    
    	DeleteObject(hbmNew);
    	DeleteDC(hdcTemp);
    	DeleteDC(hdc);
    
    	EndPaint(dvp->hWnd, &ps);
    
    	return FALSE;
    
    }

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    1. Code:
      DeleteDC(hdc);
      We should not delete a DC obtained from BeginPaint, nor the hdc passed in the wParam of WM_ERASEBKGND. You can blame the documentation(or lack thereof) on this one.
    2. Code:
      hOldFont = SelectObject(hdcTemp, dvp->hFont);
      There is no matching call to select hOldFont back in.
    3. Code:
      	//Paint the background black
      	FillRect(hdcTemp, &rect, CreateSolidBrush(dvp->bgColor));
      The return value of CreateSolidBrush() is leaking.
    4. Code:
      	FillRect(hdcTemp, &selectedRect, CreateSolidBrush(dvp->slBgColor));
      The return value of CreateSolidBrush() is leaking.
    5. Code:
      	FillRect(hdcTemp, &titleBarRect, CreateSolidBrush(dvp->fgColor));
      The return value of CreateSolidBrush() is leaking.

    That's some pretty advanced code you have there! Just out of curiosity, what OS are you running? The idea of modern (ie. 2000, XP) OSs is that leaks in one application shouldn't overly effect the rest of the system. If you're running one of those OSs, it would suggest that they haven't quite reached that point yet.

  5. #5
    Registered User Xzyx987X's Avatar
    Join Date
    Sep 2003
    Posts
    107
    Quote Originally Posted by anonytmouse
    1. Code:
      DeleteDC(hdc);
      We should not delete a DC obtained from BeginPaint, nor the hdc passed in the wParam of WM_ERASEBKGND. You can blame the documentation(or lack thereof) on this one.
    2. Code:
      hOldFont = SelectObject(hdcTemp, dvp->hFont);
      There is no matching call to select hOldFont back in.
    3. Code:
      	//Paint the background black
      	FillRect(hdcTemp, &rect, CreateSolidBrush(dvp->bgColor));
      The return value of CreateSolidBrush() is leaking.
    4. Code:
      	FillRect(hdcTemp, &selectedRect, CreateSolidBrush(dvp->slBgColor));
      The return value of CreateSolidBrush() is leaking.
    5. Code:
      	FillRect(hdcTemp, &titleBarRect, CreateSolidBrush(dvp->fgColor));
      The return value of CreateSolidBrush() is leaking.

    That's some pretty advanced code you have there!
    Thanks, but I think I may be coding above my head here since I've been having a lot of trouble debugging it...
    Quote Originally Posted by anonytmouse
    Just out of curiosity, what OS are you running? The idea of modern (ie. 2000, XP) OSs is that leaks in one application shouldn't overly effect the rest of the system. If you're running one of those OSs, it would suggest that they haven't quite reached that point yet.
    Yea, I'm running XP. And after running that code I think I'm going to have to restart my comp to get my right click menues to look right again . BTW, CreateSolidBrush is another example of inadequite documentation because nowhere does it say that you have to free the handle you create with it (well ok, except in the example code which I didn't bother to read till just now.)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with atl memory cleaning
    By Mariam1989 in forum Windows Programming
    Replies: 1
    Last Post: 11-11-2008, 12:35 PM
  2. Pointer's
    By xlordt in forum C Programming
    Replies: 13
    Last Post: 10-14-2003, 02:15 PM
  3. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  4. memory allocation problem with 2 dimensional array
    By nano_nasa in forum C++ Programming
    Replies: 7
    Last Post: 06-13-2002, 11:34 AM
  5. Memory Problem - I think...
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 10-24-2001, 12:14 PM