News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

HeapAlloc error handling

Started by Don57, January 25, 2013, 02:13:51 AM

Previous topic - Next topic

Don57

A slightly modified heap allocation routine that I found on the forum. I was curious, that if HeapCreate succeeds and HeapAlloc fails
is the HeapFree call still valid the way it is written. I would think that lp_HeapAlloc is invalid.


Create_Buffer PROC

      mov dw_HeapFail, 0                                                      ; no error yet

      invoke HeapCreate, 0 , 0 , 0
      mov lp_HeapCreate, eax

      .IF ( eax == NULL )

        mov dw_HeapFail, 1
        jmp Exit_CreateBuffer

      .ENDIF


      invoke HeapAlloc, lp_HeapCreate, HEAP_ZERO_MEMORY, MB2 
      mov lp_HeapAlloc, eax 

      .IF ( eax == NULL )

        mov dw_HeapFail, 1
        invoke HeapFree, lp_HeapCreate, 0, lp_HeapAlloc                                                   

      .ENDIF
     
   Exit_CreateBuffer:

      ret

Create_Buffer ENDP


Tedd

If HeapAlloc fails then nothing has been allocated, so there's nothing for you to free :t

Is there a reason you're creating a new heap? You can just call GetProcessHeap instead.
Potato2

qWord

Also, all that global variables aren't the best...
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

i use global variables   :P

during program init, i GetProcessHeap and store the hHeap in a global
unless you plan on freeing the block in the same PROC as it was allocated, global storage is useful

Don57

Yea I use globals, because I can access them from other proc.
Also I am too use to the old days where stack overflow was a problem, and it is my understanding that local variables are stored on the stack.

I was going to use GlobalAlloc but according to the data sheets Microsoft consider that API to be depreciated, and recommend using HeapCreate. This is my first experience with heap calls and I am unfamiliar with what the size limitations are on the process heap so I figured that it was best just to allocate a new one.

Thanks for you input. It is appreciated.

dedndave

i generally use HeapAlloc because it is simple and fast
there are cases where they tell you to use GlobalAlloc
(functions involving data streams, or the clipboard)

i wouldn't be too concerned about the "depricated" message
i suspect GlobalAlloc is going to be around for a long time

for very large allocations, VirtualAlloc may be used (perhaps as a fall-back method)


jcfuller

My old memory is failing again but I think I used to use HeapAlloc instead of GetProcessHeap because of the possibility of Heap fragmentation. If it happens I can always delete my Heap and create a new one??

James

Tedd

I don't think it's something you need to worry about.
If you're in a position to be able to delete your private heap, then presumably you either have or can free all memory allocations that belong to it. In which case, there will be no fragmentation.
Each process has its own memory space, and only you can allocate memory from that. So the only fragmentation is caused by your allocations. If you free everything then there are no fragments left to cause a problem.
(Note: some memory is allocated for loading the exe & dlls, but this exists regardless and shouldn't increase fragmentation risk.)
Potato2

Adamanteus

Basically wasn't mentioned HeapCompact - that solves problems once.

hfheatherfox07

@ Don57
Were did you find that routine ? I searched the forum and could not find it ...
I would like to see the full example.

Also does anybody have a simple example of allocating heaps?

I am still not sure when it is better to use the stack with local variables or the heap with global (dynamic allocation)
If I am using global variables , I would like to know when it i proper to allocate the blocks

I looking at my old example of animating regions ( which looked so slow with more frames )
And I suspect this has something to do with it !

Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

Adamanteus

I'm not sure that creating heap was minded by authors of Windows memory manager - how's map new heap to flat memory space ?!
That's potential ability, and I suppose that it's only for special versions with extended system memory manager, or servers. Process have one heap, returned by GetProcessHeap - others uses with system additions.

jj2007

Quote from: hfheatherfox07 on February 03, 2013, 06:11:45 AM
I am still not sure when it is better to use the stack with local variables or the heap with global...

There is a compromise: Use the .data? section. Nothing is faster ;-)

include \masm32\include\masm32rt.inc

FatBufLen=        10000000h        ; one big buffer
ForLocals=        10000h                ; plus some space for other Locals

.data?
align 16
TheBase LABEL byte
  ORG $+FatBufLen+ForLocals-1
  db ?
TheEnd LABEL byte

.code
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

start proc noargs
LOCAL somedword, rc:RECT, myR8:REAL8, FatBuffer[FatBufLen]:BYTE
  mov ebp, offset TheEnd
  mov somedword, 12345678h        ; use the locals
  mov rc.left, 12h                ; we'll print them below
  mov rc.top, 34h
  mov rc.right, 56h
  mov rc.bottom, 78h
  lea esi, FatBuffer
  mov ecx, FatBufLen
  push ecx
  print str$(ecx), " bytes allocated", 13, 10
  pop ecx
  sar ecx, 2        ; DWORDs needed for lodsd
  .Repeat
        lodsd
        .if eax
                INT 3        ; just a quick check whether the OS initialises the 256 MB properly (it does...)
        .endif
        mov [esi-4], ecx        ; let's write something to our 256MB buffer
        dec ecx
  .Until Zero?
  print hex$(rc.left), 9, "rc left", 13, 10
  inkey hex$(rc.bottom), 9, "rc bottom", 13, 10
  exit
start endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
end start

Output:
268435456 bytes allocated
00000012        rc left
00000078        rc bottom

dedndave

as far as where the memory "comes from",
there is probably little difference in allocating from the stack or from the heap
in other words, your process only gets so much total RAM   :P

if you allocate from the stack, you have to take care of detecting "insufficient memory" errors
whereas if you allocate from the heap, it tells you that there was too little memory available by returning 0

freeing stack allocated memory is a little simpler
and - the stack is a bit faster

note that you may have to probe the stack down for anything other than very small allocations
it can still be faster than HeapAlloc

heap allocation may be used globally in different PROC's

MichaelW

Considering the amount of memory that most recent systems have installed, instead of probing the stack and incurring an exception-handling delay each time you probe into the guard page, why not just tell the linker to increase the stack size, setting the reserve and commit values to whatever you anticipate needing?

Well Microsoft, here's another nice mess you've gotten us into.