News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

A question about memory allocation.

Started by minor28, May 10, 2014, 07:13:23 PM

Previous topic - Next topic

minor28

If I allocate memory with HeapAlloc the memory space is ended with two 0ABABABABh. If I increase memory with HeapReAlloc the memory space is ended with two 0ABABABABh, perhaps on a new location. In my case this is not happening. I use HEAP_ZERO_MEMORY so where the double 0ABABABABh should be the zeros continues.


invoke HeapCreate,HEAP_NO_SERIALIZE,0,0
mov hHeap,eax

invoke HeapAlloc,hHeap,HEAP_ZERO_MEMORY,1
mov pMem,eax

invoke HeapSize,hHeap,HEAP_NO_SERIALIZE,pMem
mov cursize,eax ;cursize = 1

add eax,addsize ;addsize = 25B80h
invoke HeapReAlloc,hHeap,HEAP_ZERO_MEMORY,pMem,eax
mov pMem,eax ;new location

;Fill it

;check start and end
invoke HeapSize,hHeap,HEAP_NO_SERIALIZE,pMem
add eax,pMem ;eax = end location with a double 0ABABABABh

;add additional data
invoke HeapSize,hHeap,HEAP_NO_SERIALIZE,pMem
mov cursize,eax ;cursize = 25B81h

add eax,addsize ;addsize = 11CF05h
invoke HeapReAlloc,hHeap,HEAP_ZERO_MEMORY,pMem,eax
mov pMem,eax ;new location. OK

;check start and end before fill
invoke HeapSize,hHeap,HEAP_NO_SERIALIZE,pMem
add eax,pMem ;eax = end location with lot of zeros

;Append the new data
invoke HeapSize,hHeap,HEAP_NO_SERIALIZE,pMem
;eax = 142A86h (25B81h + 11CF05h = 142A86h)

All is OK. The new data ends as it should but there are terminating zeros instead of a double 0ABABABABh.

There is no exception or other error when running this. But I wonder if it nevertheless is an error.

dedndave

using HeapReAlloc with HEAP_ZERO_MEMORY can lead to some issues

http://blogs.msdn.com/b/oldnewthing/archive/2012/03/16/10283988.aspx

Baltoro aka Zen found that one   :t

http://www.masmforum.com/board/index.php?topic=18557.0

you might be better off to use REP STOSD on reallocation to zero out the memory

minor28

It is still zeros even if not using HEAP_ZERO_MEMORY.

dedndave

that's because the OS clears old RAM for security reasons
i don't think you can rely on it being zero'ed out, especially if you allocate, free, allocate

minor28

Quotethat's because the OS clears old RAM for security reasons
i don't think you can rely on it being zero'ed out, especially if you allocate, free, allocate

The focus is not on the zero out. To zero out the memory is not important. Whatever I do it will be a lot of zeros in the space after the allocated memory. Not the ending double 0ABABABABh. There is no exception and HeapSize retrieves the correct size. Is this OK?

jj2007

Note also that HeapAlloc uses VirtualAlloc internally if you ask for a lot of memory. And the latter provides zeroed memory, whether you ask for it or not. So if you used HeapAlloc all the time, and always found zeroes: don't rely on that "feature". There could be a lot of ABABABAB if your real life program needs less than half a megabyte. Those bugs are difficult to chase...

KeepingRealBusy

I had problems using HeapAllocate (back in 2004 or so usinf XP) and worked with MS to resolv the problems. They never could resolve the problems (I don't even remember exactly what they were) but MS suggested using VirtualAlloc directly. I went to that and have never switched back. I especially like it because VirtualAlloc allocated memory in SystemPageSize blocks on a SystemPageBlock boundary (4KB allocations on 4KB bounds) and this is exactly what I needed in order to do unbufferd I/O no matter what the sector size of the disk was (either 512 or 4KB if I used my 4TB external drives).

Dave.

jj2007

Quote from: KeepingRealBusy on May 11, 2014, 04:18:58 AMMS suggested using VirtualAlloc directly. I went to that and have never switched back.

You can certainly do that for somewhat bigger memory requests in the >0.5 MB range, but for many small allocations HeapAlloc is much faster.

KeepingRealBusy

I allocate ALL of memory and then sub-allocate the parts I need (clear to 0 if necessary to re-allocate, but usually I/O buffers do not need this - I will fill the buffer and write it completely - no need to 0 clear).

Dave.

jj2007

Quote from: KeepingRealBusy on May 11, 2014, 04:54:00 AM
I allocate ALL of memory and then sub-allocate the parts I need (clear to 0 if necessary to re-allocate, but usually I/O buffers do not need this - I will fill the buffer and write it completely - no need to 0 clear).

See IsBadReadPtr and strcopy routines. Besides, if you use VirtualAlloc anyway, there is no need to clear because it is already cleared.

Gunther

Jochen,

Quote from: jj2007 on May 11, 2014, 05:08:37 AM
See IsBadReadPtr and strcopy routines. Besides, if you use VirtualAlloc anyway, there is no need to clear because it is already cleared.

interesting discussion in an old thread from 2009. :t

Gunther
You have to know the facts before you can distort them.

KeepingRealBusy

Quote from: jj2007 on May 11, 2014, 05:08:37 AM
Quote from: KeepingRealBusy on May 11, 2014, 04:54:00 AM
I allocate ALL of memory and then sub-allocate the parts I need (clear to 0 if necessary to re-allocate, but usually I/O buffers do not need this - I will fill the buffer and write it completely - no need to 0 clear).

See IsBadReadPtr and strcopy routines. Besides, if you use VirtualAlloc anyway, there is no need to clear because it is already cleared.

JJ,

There is no need to clear if you use VirtualAlloc, but only the first time. If I re-use (I will avoid saying re-alloc) the space without a VirtualFree, then I have the clear the memory myself if that is necessary (not needed in my use as a file I/O buffer that is completely filled and written).

Dave.

minor28

I can not say that I was wiser after this discussion. However my app is working without the two ABABABAB (at least on win7 32) and I never rely on the zeros.

My question arose when I wrote a demonstration program on how to use my dictionary functions.

See http://masm32.com/board/index.php?PHPSESSID=ceae84604fb622ab7c4bc196ad7accb7&topic=3175.0

jj2007

Quote from: minor28 on May 11, 2014, 05:02:15 PM
I can not say that I was wiser after this discussion.

It's complex, but the essential rules are:
- VirtualAlloc zeroes everything and is OK for big allocations (>0.5MB)
- HeapAlloc zeroes only what you explicitly asked for and is best for many small allocations (1 byte..0.5MB)
- don't rely on "free" extra bytes, i.e. the difference between what HeapSize reports and what you had requested
- if you intend to use functions dealing with zero-delimited strings, like strlen, strcpy etc, a) make sure that you request one extra byte, i.e. filelen+1 and b) zero that byte yourself, because ReadFile won't do it for you.