Re: HeapFree() Failure

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



If HeapFree fails, that's usually an indication of heap corruption -
underwriting or overwriting the bounds of an allocated block. In your case,
overwriting.

Btw, HeapAlloc(GetProcessHeap(), ...) is equivalent to calling
LocalAlloc() - and, as Paul pointed out, GlobalAlloc.


Change this line:

pCaps=(wchar_t**)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,iNumColumns*sizeof(wchar_t));

to this:

pCaps=(wchar_t**)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,iNumColumns*sizeof(wchar_t*));

After all, you are storing pointers to wchar_t, not wchar_t.
sizeof(wchar_t) is 2 and sizeof(wchar_t*) is 4.


--
Michael Salamone [eMVP]
Entrek Software, Inc.
www.entrek.com


"Fred Harris" <FredHarris@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:0D0EC65D-63CE-4AC6-AF23-1E5CBEE8773A@xxxxxxxxxxxxxxxx
The below program is essentially a 'Hello, World!' program without the
'Hello, World!' that does, however, create a window, and makes room for
eight extra .cbWndExtra bytes in the window class structure. In the first
four bytes it SetWindowLong()'s the number four, which is the number of
globally defined strings it declares like so:

wchar_t *szCaptions[]={L"Fred",L"Elsie",L"Mark",L"Joanne"};

In the second four bytes it stores the wchar_t** it obtains from
HeapAlloc(). Sixteen bytes are successfully allocated to store pointers
to
the four strings. All this stuff it does in WndProc_OnCreate(lpWEA wea),
which is the message handling function for the WM_CREATE message. Also in
that function it obtains storage and pointers for the four globally
allocated
strings from more HeapAlloc() calls, and it stores these pointers in the
sixteen bytes pointed to by the wchar_t** in the cbWndExtra bytes.

My problem here is that in the processing of the WM_CLOSE message in
WndProc_OnClose() the first of the four strings is failing in the
de-allocation call of HeapFree(). Everywhere else the HeapFree() calls
are
succeeding, but not for the first of the strings, i.e., my name "Fred".
Note
the zero after "Fred" in the output log file below. First is the output
log
file and below that is the full Windows CE program. The program runs on a
Juniper Systems Allegro CX and I used Microsoft eMbedded Visual C++ 4.0.
The
Active Platform is ALLEGRO CX - STANDARD SDK 420. It uses ArmV4
processor.

Can anyone spot what I am doing wrong?


\\C_DRIVE\Output.txt Opened In WinMain()

Entering WndProc_OnCreate()
iNumColumns=4
hHeap=469958656
pCaps=197168
0 Fred
1 Elsie
2 Mark
3 Joanne
Exiting WndProc_OnCreate(). Bye!!!

Entering WndProc_OnClose()
iColumns=4
0 197184 Fred
1 197216 Elsie
2 197248 Mark
3 197280 Joanne

hHeap=469958656

i &ptr[i] ptr[i] ptr[i] HeapFree(hHeap,0,ptr[i])
===========================================================================
0 197168 197184 Fred 0
1 197172 197216 Elsie 1
2 197176 197248 Mark 1
3 197180 197280 Joanne 1

blnFree=1
\\C_DRIVE\Output.txt Closed In WndProc_OnClose()
Exiting WndProc_OnClose()

//Code
#include <windows.h>
wchar_t *szCaptions[]={L"Fred",L"Elsie",L"Mark",L"Joanne"};
HANDLE hFile=0;

typedef struct WndEventArgs
{
HWND hwnd;
HINSTANCE hInst;
WPARAM wParam;
LPARAM lParam;
}WEA,*lpWEA;

struct EVENTHANDLER
{
unsigned int Code;
long (*fnPtr)(lpWEA);
}EventHandler[2];

long WndProc_OnCreate(lpWEA wea)
{
unsigned int iNumColumns,i;
static wchar_t szBuffer[256];
HANDLE hHeap;
wchar_t **pCaps;
wchar_t *pStorage;
DWORD cWritten;

wsprintf(szBuffer,L"Entering WndProc_OnCreate()\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

//Get Number of Columns.
iNumColumns=sizeof(*szCaptions);
wsprintf(szBuffer,L"iNumColumns=%u\r\n",iNumColumns);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
SetWindowLong(wea->hwnd,0,iNumColumns);

//Get Memory To Store Names/Captions with HeapAlloc()
hHeap=GetProcessHeap();
wsprintf(szBuffer,L"hHeap=%u\r\n",hHeap);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
//This memory allocation call will give me sixteen bytes to store four
//wchar_t string pointers

pCaps=(wchar_t**)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,iNumColumns*sizeof(wchar_t));
wsprintf(szBuffer,L"pCaps=%u\r\n",pCaps);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
SetWindowLong(wea->hwnd,4,(long)pCaps); //store **ptr
for(i=0;i<iNumColumns;i++)
{
//The below calls will give me memory to store the four strings
themselves, and
//of course, the szCaption strings need to be copied to the pointed to
locations.

pStorage=(wchar_t*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,(wcslen(szCaptions[i])+1)*sizeof(wchar_t));
wcscpy(pStorage,szCaptions[i]);
//Then of course store the string pointers in the sizteen bytes
allocated
//for the four pointers.
pCaps[i]=pStorage;
wsprintf(szBuffer,L"%u\t%s\r\n",i,szCaptions[i]);

WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
}
wsprintf(szBuffer,L"Exiting WndProc_OnCreate(). Bye!!!\r\n\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

return 0;
}

long WndProc_OnLButtonDown(lpWEA wea)
{
SendMessage(wea->hwnd,WM_CLOSE,0,0);
return 0;
}

long WndProc_OnClose(lpWEA wea)
{
static wchar_t szBuffer[256];
unsigned int i,iColumns;
DWORD cWritten;
BOOL blnFree=0;
HANDLE hHeap;
wchar_t **ptr;

wsprintf(szBuffer,L"Entering WndProc_OnClose()\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
iColumns=GetWindowLong(wea->hwnd,0);
wsprintf(szBuffer,L"iColumns=%u\r\n",iColumns);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
ptr=(wchar_t**)GetWindowLong(wea->hwnd,4);
for(i=0;i<iColumns;i++)
{
//wsprintf(szBuffer,L"%u\t%u\t%s\r\n",i,*(ptr+i),*(ptr+i));
wsprintf(szBuffer,L"%u\t%u\t%s\r\n",i,ptr[i],ptr[i]);

WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
}
wsprintf(szBuffer,L"\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

hHeap=GetProcessHeap();
wsprintf(szBuffer,L"hHeap=%u\r\n\r\n",hHeap);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

wsprintf(szBuffer,L"i\t&ptr[i]\tptr[i]\t\tptr[i]\t\tHeapFree(hHeap,0,ptr[i])\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

wsprintf(szBuffer,L"===========================================================================\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
for(i=0;i<iColumns;i++)
{
//blnFree=HeapFree(hHeap,0,*(ptr+i));

wsprintf(szBuffer,L"%u\t%u\t%u\t\t%s\t\t%u\r\n",i,&ptr[i],ptr[i],ptr[i],HeapFree(hHeap,0,ptr[i]));

WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
}
wsprintf(szBuffer,L"\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
blnFree=HeapFree(hHeap,0,ptr);
wsprintf(szBuffer,L"blnFree=%u\r\n",blnFree);
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);

wsprintf(szBuffer,L"\\\\C_DRIVE\\Output.txt Closed In
WndProc_OnClose()\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
wsprintf(szBuffer,L"Exiting WndProc_OnClose()\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
CloseHandle(hFile);
PostQuitMessage(0);

return 0;
}

void AttachEventHandlers(void)
{
EventHandler[0].Code=WM_CREATE,
EventHandler[0].fnPtr=WndProc_OnCreate;
EventHandler[1].Code=WM_LBUTTONDOWN,
EventHandler[1].fnPtr=WndProc_OnLButtonDown;
EventHandler[2].Code=WM_CLOSE,
EventHandler[2].fnPtr=WndProc_OnClose;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
unsigned int i;
static WEA Wea;

for(i=0;i<3;i++)
{
if(EventHandler[i].Code==message)
{
Wea.hwnd=hwnd,Wea.lParam=lParam,Wea.wParam=wParam;
return (*EventHandler[i].fnPtr)(&Wea);
}
}

return (DefWindowProc(hwnd,message,wParam,lParam));
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR
lpCmdLine,int nCmdShow)
{
wchar_t szName[]=L"Start14";
DWORD cWritten,dwStyle;
wchar_t szBuffer[256];
WNDCLASS wndClass;
HWND hwndMain;
MSG msg;
RECT rc;

AttachEventHandlers();
wndClass.lpszClassName=szName;
//wndClass.style=WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU;
wndClass.style=0;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 8;
wndClass.hInstance = hInstance; wndClass.hIcon = NULL;
wndClass.lpszMenuName = NULL; wndClass.hCursor = NULL;
wndClass.hbrBackground =
(HBRUSH)GetStockObject(WHITE_BRUSH);
RegisterClass(&wndClass);
SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);

hFile=CreateFile(L"\\C_DRIVE\\Output.txt",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
wsprintf(szBuffer,L"\\\\C_DRIVE\\Output.txt Opened In WinMain()\r\n\r\n");
WriteFile(hFile,szBuffer,wcslen(szBuffer)*sizeof(wchar_t),&cWritten,NULL);
dwStyle=WS_OVERLAPPED | WS_VISIBLE | WS_SYSMENU;

hwndMain=CreateWindow(szName,szName,dwStyle,0,0,rc.right,rc.bottom,0,0,hInstance,0);
while(GetMessage(&msg,NULL,0,0)==TRUE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}



.



Relevant Pages

  • Re: HeapFree() Failure
    ... HeapAllocand HeapFreecalls with GlobalAlloc() and GlobalFree ... globally defined strings it declares like so: ... Sixteen bytes are successfully allocated to store pointers ...
    (microsoft.public.windowsce.embedded)
  • RE: HeapFree() Failure
    ... HeapAllocand HeapFreecalls with GlobalAlloc() and GlobalFree ... globally defined strings it declares like so: ... Sixteen bytes are successfully allocated to store pointers to ...
    (microsoft.public.windowsce.embedded)
  • Re: HeapFree() Failure
    ... After all, you are storing pointers to wchar_t, not wchar_t. ... globally defined strings it declares like so: ... Sixteen bytes are successfully allocated to store pointers ... All this stuff it does in WndProc_OnCreate(lpWEA wea), ...
    (microsoft.public.windowsce.embedded)
  • HeapFree() Failure
    ... globally defined strings it declares like so: ... Sixteen bytes are successfully allocated to store pointers to ... All this stuff it does in WndProc_OnCreate(lpWEA wea), ...
    (microsoft.public.windowsce.embedded)
  • Re: Any way to take a word as input from stdin ?
    ... You want to sort many words, so you will need to store ... number of pointers to char (which can be reallocated if it proves to be ... The pointers to char ... That's why you use dynamic allocation - it means ...
    (comp.lang.c)