Very weird allocation problem

Started by
5 comments, last by JonW 18 years, 1 month ago
I have the following allocating code: BYTE *pData = new BYTE[uWidth*uHeight*3]; BYTE *pGray = new BYTE[uWidth*uHeight]; The call to new for pData always returns a valid pointer. However, allocating memory for pGray always fails (it is set to either 0 or an invalid pointer depending on where in the function I put the line) when uWidth is 367 and uHeight is 119; any other time, pGray allocates fine, including very large values for uWidth and uHeight. I haven't tried all possible combinations, but it always fails for 367x119. This is really weird. Any ideas?
Advertisement
Tried doing a clean build? This sounds like stack corruption to me. Try commenting out parts of the function until the error goes away; or post the whole function (if it's not to huge) here. If you feel brave, you could also try stepping into the CRT source if you have it, that'll give you a better idea why it fails.
I tried commenting out the allocation of pGray, and now it fails when I delete pData. Here is the code:
void Screenshot (HWND hWnd){	HDC hDC = GetWindowDC(hWnd);	HDC hMemDC = CreateCompatibleDC(hDC);	UINT uWidth, uHeight;	RECT rc;	GetWindowRect(hWnd, &rc);	uWidth = rc.right-rc.left;	uHeight = rc.bottom-rc.top;	HBITMAP hBitmap = CreateCompatibleBitmap(hDC, uWidth, uHeight);	SelectObject(hMemDC, hBitmap);	// Copy screen to memory DC	BitBlt(hMemDC, 0, 0, uWidth, uHeight, hDC, 0, 0, SRCCOPY);	// Allocate memory for the bitmap data	BYTE *pData = new BYTE[uWidth*uHeight*3];	BITMAPINFO bmInfo;	bmInfo.bmiHeader.biSize = sizeof(bmInfo);	bmInfo.bmiHeader.biWidth = uWidth;	bmInfo.bmiHeader.biHeight = uHeight;	bmInfo.bmiHeader.biPlanes = 1;	bmInfo.bmiHeader.biBitCount = 24;	bmInfo.bmiHeader.biCompression = BI_RGB;	bmInfo.bmiHeader.biSizeImage = 0;	bmInfo.bmiHeader.biXPelsPerMeter = 0;	bmInfo.bmiHeader.biYPelsPerMeter = 0;	bmInfo.bmiHeader.biClrUsed = 0;	bmInfo.bmiHeader.biClrImportant = 0;	GetDIBits(hMemDC, hBitmap, 0, uHeight, pData, &bmInfo, DIB_RGB_COLORS);	delete[] pData;         // <-- crashes here	DeleteObject(hBitmap);	DeleteDC(hMemDC);	ReleaseDC(0, hDC);}


It only crashes when the window is certain dimensions. It originally crashed when I passed it the handle to RealPlayer, so I figured there was something weird with that window. But when I try resizing Explorer to the same dimensions and pass its handle to the function it also crashes.

I tried rebuilding, and it crashes in both Debug and Release. If I comment out the call to GetDIBits it works OK, so maybe it is overwriting the end of pData or something. But all the parameters seem OK, and like I said it is only for certain window sizes...

It seems like you aren't getting the alignment right. You probably need to round the width up to the next multiple of 4 in order for the data to get read in correctly without writing past the memory allocated.
Bitmaps have to have a width that's divisible by 4. So, try allocating a slightly larger buffer (If your width was going to be 301, it should be 304 for instance). So, you're overrunning your buffer.

EDIT: Bah, 6 seconds too slow [smile]
maybe try deleting your array last? I'm not sure how GetDIBBits work, but perhaps its linking your buffer to the device context or bitmap. So when you go to DeleteObject, or DeleteDC, maybe it attempts to do something with the pData- which has already been released. This is just a guess though...maybe try MSDN for info on GetDIBBits

[edit]
wow, 2 minutes too slow..and completely wrong as well =)
moe.ron
Yep, it was the alignment. I knew the DWORD width was required when saving bitmaps to disk, but I guess I didn't think about that being necessary for the GDI bitmap functions. Doh.

Thanks guys.

This topic is closed to new replies.

Advertisement