How to freeup the memory...

J

Jigar Mehta

Hye,
I am using one object which allocates around 2 MB of memory.. Now after
use, I want it to free. But the task can not be done. the memory is still
allocated and not freed. I am using it in thread. so, next time when thread
runs, whole block is allocated for the second time and in just 10 tries, my
PC got hang because of memory problem. I know GlobalFree(HGLOBAL) function
and already used it but in vain.. So, is there any function that I can run
after one turn of my thread (after which I don't want that memory at all.)
So, if the whole area is deleted then also it will be OK.
 
J

Jeff Partch [MVP]

Jigar Mehta said:
Hye,
I am using one object which allocates around 2 MB of memory.. Now after
use, I want it to free. But the task can not be done. the memory is still
allocated and not freed. I am using it in thread. so, next time when thread
runs, whole block is allocated for the second time and in just 10 tries, my
PC got hang because of memory problem. I know GlobalFree(HGLOBAL) function
and already used it but in vain.. So, is there any function that I can run
after one turn of my thread (after which I don't want that memory at all.)
So, if the whole area is deleted then also it will be OK.

You're saying here that you're using GlobalAlloc and a corresponding
GlobalFree doesn't? That just doesn't sound right to me. What does
GlobalFree return? If not NULL, what does GetLastError return?
 
J

Jigar Mehta

Actually I am using functions of WinCap, (MSDN Sample) in that everytime I
capture desktop, I lose 3 MB of memory...

Can you help me after seeing the WinCap & testing it!!...

Jigar Mehta said:
Hye,
I am using one object which allocates around 2 MB of memory.. Now after
use, I want it to free. But the task can not be done. the memory is still
allocated and not freed. I am using it in thread. so, next time when thread
runs, whole block is allocated for the second time and in just 10 tries, my
PC got hang because of memory problem. I know GlobalFree(HGLOBAL) function
and already used it but in vain.. So, is there any function that I can run
after one turn of my thread (after which I don't want that memory at all.)
So, if the whole area is deleted then also it will be OK.

You're saying here that you're using GlobalAlloc and a corresponding
GlobalFree doesn't? That just doesn't sound right to me. What does
GlobalFree return? If not NULL, what does GetLastError return?
 
J

Jigar Mehta

Hye Jeff,

Sorry If you are confused from my questions... Actually What I am doing
is, Capturing window into a bitmap file, saving it to BMP (with RLE8
compression), so for saving it to disk, I am creating a hell lot of
variables to handle all the complexity. Now, as you told, my GlobalFree
returns NULL, so, that object is freedup, but the problem is for other
objects of structures and variables that I created to save it to disk. How
to free that.. e.g. here is a snippet of code...
----------------------------------------------------------------------------
-------------
//code starts here... (it is a small function that allocates memory for DIB)
----------------------------------------------------------------------------
-------------
HANDLE CDV_ClientDlg::AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap,
HWND hwnd)
{
// Figure out the size needed to hold the BITMAPINFO structure
// (which includes the BITMAPINFOHEADER and the color table).
dwLen = bi.biSize + PaletteSize((LPSTR) &bi);
hDIB = GlobalAlloc(GHND,dwLen);
// Check that DIB handle is valid
if (!hDIB)
return NULL;
// Set up the BITMAPINFOHEADER in the newly allocated global memory,
// then call GetDIBits() with lpBits = NULL to have it fill in the
// biSizeImage field for us.
lpbi_2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi_2 = bi;
hDC_1 = CreateDC ( TEXT("DISPLAY"), NULL, NULL, NULL );
GetDIBits(hDC_1, hBitmap, 0, (UINT) bi.biHeight, NULL, (LPBITMAPINFO)lpbi_2,
DIB_RGB_COLORS);
::ReleaseDC(hwnd, hDC_1);
// If the driver did not fill in the biSizeImage field,
// fill it in -- NOTE: this is a bug in the driver!
if (lpbi_2->biSizeImage == 0)
lpbi_2->biSizeImage = WIDTHBYTES((DWORD)lpbi_2->biWidth *
lpbi_2->biBitCount) * lpbi_2->biHeight;
// Get the size of the memory block we need
dwLen = lpbi_2->biSize + PaletteSize((LPSTR) &bi) + lpbi_2->biSizeImage;
// Unlock the memory block
GlobalUnlock(hDIB);
// ReAlloc the buffer big enough to hold all the bits
if (hTemp = GlobalReAlloc(hDIB,dwLen,0))
return hTemp;
else
{
// Else free memory block and return failure
GlobalFree(hDIB);
return NULL;
}
}
HANDLE CDV_ClientDlg::AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap,
HWND hwnd)
{
// Figure out the size needed to hold the BITMAPINFO structure
// (which includes the BITMAPINFOHEADER and the color table).
dwLen = bi.biSize + PaletteSize((LPSTR) &bi);
hDIB = GlobalAlloc(GHND,dwLen);
// Check that DIB handle is valid
if (!hDIB)
return NULL;
// Set up the BITMAPINFOHEADER in the newly allocated global memory,
// then call GetDIBits() with lpBits = NULL to have it fill in the
// biSizeImage field for us.
lpbi_2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi_2 = bi;
hDC_1 = CreateDC ( TEXT("DISPLAY"), NULL, NULL, NULL );
GetDIBits(hDC_1, hBitmap, 0, (UINT) bi.biHeight, NULL, (LPBITMAPINFO)lpbi_2,
DIB_RGB_COLORS);
::ReleaseDC(hwnd, hDC_1);
// If the driver did not fill in the biSizeImage field,
// fill it in -- NOTE: this is a bug in the driver!
if (lpbi_2->biSizeImage == 0)
lpbi_2->biSizeImage = WIDTHBYTES((DWORD)lpbi_2->biWidth *
lpbi_2->biBitCount) * lpbi_2->biHeight;
// Get the size of the memory block we need
dwLen = lpbi_2->biSize + PaletteSize((LPSTR) &bi) + lpbi_2->biSizeImage;
// Unlock the memory block
GlobalUnlock(hDIB);
// ReAlloc the buffer big enough to hold all the bits
if (hTemp = GlobalReAlloc(hDIB,dwLen,0))
return hTemp;
else
{
// Else free memory block and return failure
GlobalFree(hDIB);
return NULL;
}
}
----------------------------------------------------------------------------
-------------
//code ends here
----------------------------------------------------------------------------
-------------
Now here you can see that I am allocating some memory, after that I Save the
bitmap and then I want to free these memory.. All variables used are global
so, I will be able to free them up later.. But free() method gives me error
for lpbi_2 i.e. free(lpbi_2) gives runtime error (that abort dialog)...

If you are still confused and want a full application code, (want to help me
really), Please tell me, I will send you full application (of VC.NET). I am
tired of this as I am trying to do this from last 4 hours.)
 
J

Jeff Partch [MVP]

Jigar Mehta said:
Now here you can see that I am allocating some memory, after that I Save the
bitmap and then I want to free these memory.. All variables used are global
so, I will be able to free them up later.. But free() method gives me error
for lpbi_2 i.e. free(lpbi_2) gives runtime error (that abort dialog)...

Hi,

The only objects I see that need to be 'freed' are the HDC, and the HGLOBALs
hDib and hTemp. You obtain the HDC using CreateDC but then call ReleaseDC on
it. Rather you should use DeleteDC, I think. Otherwise, hDib seems local to
the function and seems properly managed to me. The hTemp is a return value,
so it is the caller's responsibility to call GlobalFree on it when it is
done. Nothing really seems to warrant a global or member variable (although
dwLen might be handy for future reference). You mention that using free is
failing -- as well it should. Nothing in the above needs to be passed to
free. Certainly not lpbi_2, that is not something that needs to deallocated
at all.

FWIW, I wrote the thing like so...

HANDLE AllocRoomForDIB(VOID)
{
DWORD dwLen = 1000;
HGLOBAL hDIB = GlobalAlloc(GHND,dwLen);
LPBITMAPINFOHEADER lpbi_2;
HGLOBAL hTemp;
// Check that DIB handle is valid
if (!hDIB)
return NULL;
lpbi_2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
GlobalUnlock(hDIB);
dwLen *= 3000;
hTemp = GlobalReAlloc(hDIB,dwLen,0);
if (hTemp)
return hTemp;
else
{
// Else free memory block and return failure
OutputDebugString(_T("Freeing in ERROR\n"));
if ((BOOL)GlobalFree(hDIB))
OutputDebugString(_T("\tFAILURE to free\n"));
}
return NULL;
}

....and called it like so...

INT
WINAPI
_tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpszCmdLine,
INT nCmdChow
)
{
INT i;
for (i = 0; i < 1000; i++)
{
HANDLE hRet = AllocRoomForDIB();
if (hRet)
{
OutputDebugString(_T("Freeing in CALLER\n"));
if ((BOOL)GlobalFree(hRet))
OutputDebugString(_T("\tFAILURE to free\n"));
}
Sleep(100);
}
return 0;

// Unused
hInstance;
hPrevInstance;
lpszCmdLine;
nCmdChow;
}

....and it never seemed to report either failure or error.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top