To the Ineffable All,

    I have been writing a program that uses INVOKE LocalAlloc,LPRT,EAX to obtain some memory.  The problem comes when releasing memory via INVOKE LocalFree,EAX.  The LastError operation shows problem to be 'Invalid Handle'.  I made damn sure the value of EAX was the same for LocalFree as it was for LocalAlloc.  Also the allocated memory does not get overwritten by parts of the program that should not do so.  Now, sometimes just increasing the allocation request by just 1 byte will make the trouble go away.  Other times I need to request a big gob of extra memory that I do not need in order to keep the error from happening. My OS is XP with SP2.  Any ideas or suggestions?  Ratch
Posted on 2006-03-23 14:11:47 by Ratch
Hi Ratch,

Unless you have a specific reason for using LocalAlloc (though I can't think of one off the top of my head) you should use the virtual memory functions or at the very least the Heap functions. I have never used LocalAlloc but the docs say it should return NULL so you definitely have a problem there. I would begin by verifying that the memory was actually allocated by verifying the return from LocalAlloc.
Posted on 2006-03-23 19:19:13 by donkey
Donkey,
   

I would begin by verifying that the memory was actually allocated by verifying the return from LocalAlloc.


    Yes, I certainly have verified that the memory was alloted and used.  The OS just does not want to take the memory back.  I never had any probs with LocalAlloc/LocalFree before, and they are so simple to use. But I guess that I will have to get up to speed and use virtual memory functions.  Ratch
Posted on 2006-03-23 19:30:19 by Ratch
Hi Ratch,

Pretty easy to use, just a couple of extra parameters for simple allocations use the following:

invoke VirtualAlloc,NULL,,MEM_COMMIT,PAGE_READWRITE
test eax,eax
jz >.ERROR
mov ,eax

invoke VirtualFree,,0,MEM_RELEASE
Posted on 2006-03-23 21:35:09 by donkey
Donkey,
    Thanks for your advice.  I put some selective MessageBox insertions within my code to help track what was going on, and discovered I did not allocate enough memory for a sub-task after all.  That screwed up everything so badly that even OllyDbg gave different results from that of a straight execution.  So I had to use alterate methods of debugging with MessageBoxes.  When I corrected my mistake, all the strange and spooky behavior disappeared, and LocalAlloc/Free works fine now.  I have to say that LocalAlloc is simpler to use, and if I don't need all the whiz bang things Virtual Allocation can do, I prefer to use it. Thanks again for your attention to this problem.  Ratch
Posted on 2006-03-23 23:09:16 by Ratch
all the strange and spooky behavior disappeared, and LocalAlloc/Free works fine now

Same, here, sometimes LocalAlloc/GlobalAlloc does behave spooky.

One surefire way (worked for me atleast) was to use LocalLock/GlobalLock on the return value of LocalAlloc/GlobalAlloc, like so

invoke LocalAlloc,LPRT,sizeof MYSTRUCT
invoke LocalLock,eax
mov hMem,eax


Also, sometimes it works fine without LocalLock  :shock:
Posted on 2006-03-24 03:02:03 by shantanu_gadgil
shantanu_gadgil,

invoke LocalAlloc,LPRT,sizeof MYSTRUCT
invoke LocalLock,eax
mov hMem,eax



    Thanks for your input.  I haven't had a need to lock the allocation, especially when using the LPRT option.  My problem was that I was writing past my allocation, which locking will not prevent.  By the way, you don't need the sizeof directive for the above code.  MASM will substitute the number of bytes defined by MYSTRUCT just by its name only.  I've seen a lot of code where sizeof is redundant.  Ratch

invoke LocalAlloc,LPRT,MYSTRUCT
Posted on 2006-03-24 10:58:19 by Ratch
Never, never failed me:

.586
.model flat,stdcall
option casemap:none

public HEAP1
public malloc_func
public free_func
public realloc_func

HEAP_ZERO_MEMORY equ 00000008h     

.data
HEAP1 dd 0
.code

HeapCreate proto :DWORD,:DWORD,:DWORD
HeapAlloc proto :DWORD,:DWORD,:DWORD
HeapFree proto :DWORD,:DWORD,:DWORD
HeapReAlloc proto :DWORD,:DWORD,:DWORD,:DWORD

malloc_func proc PUBLIC uses ebx ecx edx esi edi How
.if !HEAP1
invoke HeapCreate,0,10000,0
mov HEAP1,eax
.endif
invoke HeapAlloc,HEAP1,HEAP_ZERO_MEMORY,How
ret
malloc_func endp

free_func proc PUBLIC uses eax ebx ecx edx esi edi What
invoke HeapFree,HEAP1,0,What
ret
free_func endp

realloc_func proc PUBLIC uses ebx ecx edx esi edi What,How
.if !HEAP1
invoke HeapCreate,0,10000,0
mov HEAP1,eax
.endif
.if !What
.if How
invoke HeapAlloc,HEAP1,HEAP_ZERO_MEMORY,How
.else
xor eax,eax
.endif
.else
.if How
invoke HeapReAlloc,HEAP1,HEAP_ZERO_MEMORY,What,How
.else
invoke HeapFree,HEAP1,0,What
xor eax,eax
.endif
.endif
ret
realloc_func endp
end


Also, macros for ease:

malloc_func proto :DWORD
free_func proto :DWORD
realloc_func proto :DWORD,:DWORD


malloc MACRO How:REQ
invoke malloc_func,How
exitm <eax>
ENDM

free MACRO What
invoke free_func,What
ENDM

realloc MACRO WHat:REQ,How:REQ
invoke realloc_func,WHat,How
exitm <eax>
endm
Posted on 2006-03-24 18:56:26 by Ultrano
"HeapAlloc for the win" :)

Btw it's a *very* good idea to use macros for (re)allocation, free, etc, instead of directly calling the allocation functions (whether you use heapalloc, virtualalloc, local/globalalloc or your grandmother). This way, you can add instrumentation and logging, which helps *A LOT* with tracking down leaks and over/underruns.
Posted on 2006-03-25 09:17:22 by f0dder

If you were using ObjAsm32 macros, you could take advantage of the MemAlloc and MemFree macros. They just wrap HeapAlloc functionality in actual fact.
They are in my TOP 3 reasons for choosing to support and use ObjAsm32.
-memory and string macros
-oop macros
-debug macros


Now:
mov pMyThingy, $MemAlloc (sizeof MyThingy,MEM_INIT_ZERO)
...
...
Later:
MemFree pMyThingy



OA32 - Bridging the language generation gap.
OA32 - Reduce, Reuse, Recycle.
OA32 - Making the virtual world a nicer place in which not to exist.

That's right, as seen on TV, ObjAsm32 is COMPLETELY FREE, including for commercial purposes.
Have fun, kids :)
Posted on 2006-03-31 02:00:15 by Homer