Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ MFC
why it return NULL? And How can I fix it?
 
I had used GetLastError() to catch error code and it return 6 (invalid Handle).
But I dont know why.
 
Help me to sold it, thanks so much..
 
Untill now, I havent solution to fix this problem.
Posted 6-Mar-13 16:17pm
Hieu388427
Edited 8-Mar-13 0:50am
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Even if you follow a 'memory allocate' request with a 'free', a reasonable size memory request might not be available after some time. If the allocations are 'large' or are different sizes (or several other reasons), the memory available will get fragmented over time and memory will not be available. Fact of life.
 
Some of the things you can do to help with the situation:
- Use new and delete (not malloc/calloc/realloc/free)
- Implement a memory pool
- Allocate what you can on the stack
- Make sure you don't have leaks
- If you allocate/free something in a loop, do the 'free' logic in the reverse order from allocations
- If have a heap based buffer, start it with a reasonably 'large' size and expand it if it becomes too small. Hang on to this 'largest' size buffer.
  Permalink  
Comments
Hieu388 at 7-Mar-13 21:45pm
   
Thanks H.Prydon so much.

But it's still have problem..
 
When it occur applycation error. I used code below to show physical memory.
///////////////////////////////////////////////
MEMORYSTATUS MemStat;

memset(&MemStat, 0, sizeof(MemStat));
MemStat.dwLength=sizeof(MemStat);
GlobalMemoryStatus(&MemStat);

int nAvailPhysMB = MemStat.dwAvailPhys / (1024*1024);
//////////////////////////////////////////////
I see available physical memory is over 200MB. I dont think that application error from memory leak.

I also use GetLastError() to get error code. It return 6 "Invalid handle" but what is handle in here?

This is my direct code:
//
pDIB = (BYTE*)GlobalAllocPtr( GHND, DIBsize ) ;
//
Jochen Arndt at 8-Mar-13 5:36am
   
GlobalAllocPtr() is a macro: GlobalLock(GlobalAlloc((flags), (cb)))
When there is not enough memory, GlobalAlloc() will fail and return NULL. The return type of GlobalAlloc() is a HGLOBAL: A handle to a global memory object. When passing such a NULL handle to GlobalLock(), it will return NULL and set the last error to 6 (ERROR_INVALID_HANDLE).
 
So it seems that you are using up all your memory. A possible reason is that you are not freeing your memory. When using GlobalAllocPtr(), the memory must be freed using GlobalFreePtr(). When passing the memory object to the system, it must be unlocked before. Otherwise the system can't free it because there is still a lock count:
 
pDIB = (BYTE*)GlobalAllocPtr( GHND, DIBsize );
// Copy data to memory here
// Option1: Memory no longer used: Free it using GlobalFreePtr(pDIB)
// Option2: Unlock the memory before passing it to
// somewhere else that takes ownership of the memory:
HGLOBAL hGlobal = GlobalPtrHandle(pDIB);
GlobalUnlock(hGlobal);
// Pass global memory to function that takes ownership of the memory
FuncExpectingAHGLOBAL(hGlobal);
Hieu388 at 8-Mar-13 6:15am
   
Thanks for your help.
In Option 1: I had used and this error still have.
In Option 2: I will try it and report to you later.
 
I have a question: When size need to allocate larger than 512KB, GlobalAllocPtr() does not using Heap memory any more, in this case GlobalAllocPtr() using direct Virtual Memory to allocate memory. And then when free memory by GlobalFreePtr(), does it work? because I think GlobalFreePtr() work in Heap memory, not in Virtual Memory
Any help from you?
Thank you so much.
Jochen Arndt at 8-Mar-13 6:31am
   
GlobalAlloc() memory is on the heap. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa366574%28v=vs.85%29.aspx.
 
In general you should use global memory only when it is required (passed as parameter to some function, e.g. clipboard and drag & drop operations).
In all other cases you should use new / delete.
 
I would also suggest to not use the macros. Use the pure functions. So you have a better overview of the usage and locking and can check for errors when they occur and not later (if GlobalAlloc() fails it will set an error code which is overwritten by GlobalLock() when using the GlobalAllocPtr() macro):
 
HGLOBAL hGlobal = ::GlobalAlloc(nSize);
if (NULL == hGlobal)
{
// out of memory; show error message and/or return failure state
return; // out of memory
}
// Lock the memory and get a pointer to it
pDIB = (LPBYTE)::GlobalLock(hGlobal);
// Do something with the memory
::CopyMemory(pDIB, lpSrc, nSize);
// Pass memory to other function to do somethin with it
SomeFunc(pDIB);
// Unlock memory so that it can be accessed by others and freed
::GlobalUnlock(hGlobal);
// Pass global memory to other function
SomeFunc(hGlobal);
// If function does not take ownership of memory, free it
::GlobalFree(hGlobal);
Hieu388 at 7-Mar-13 21:48pm
   
I also make size lager when it small. above 512* 1024 bytes, but it's still happen.
It occur when run >1500 times. Do you give me a hint?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

You didn't call GetLastError as recommended by the documentation[^], did you?
  Permalink  
Comments
Hieu388 at 8-Mar-13 6:21am
   
I called GetLastError after GlobalAllocPtr() return NULL.
 
/////////////////////////////
pUpdateImageDIB = (BYTE*)GlobalAllocPtr( GHND, DIBsize ) ;
if( pUpdateImageDIB == NULL )
{
DWOR dwError = GetLastError() ;
}
/////////////////////
I see it return 6 (Invalid Handle).
I dont know why? Because I had used GlobalFreePtr() to free memory.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 280
1 Sergey Alexandrovich Kryukov 279
2 CPallini 205
3 Maciej Los 162
4 Afzaal Ahmad Zeeshan 160
0 OriginalGriff 5,635
1 DamithSL 4,496
2 Maciej Los 3,942
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,180


Advertise | Privacy | Mobile
Web04 | 2.8.141216.1 | Last Updated 8 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100