flat assembler
Message board for the users of flat assembler.

Index > Windows > What is the difference btwn VirtualAlloc & HeapAlloc?

Author
Thread Post new topic Reply to topic
EaxRax



Joined: 20 Jul 2013
Posts: 15
EaxRax 15 Aug 2013, 12:39
Hello, people! Very Happy I'm not new to assembly language, but new to programming under Windows.
Since I need to allocate memory for my program, I looked for a memory allocation functions. And I found: VirtualAlloc and HeapAlloc.

In this regard, I have two questions:
1. What is the difference between a function VirtualAlloc and HeapAlloc? I am very confused by the word Virtual, in a function VirtualAlloc. I've read the MSDN documentation, but i still don't understand difference between this API functions. Confused If possible, detail!.
2. What function better?

Thanks.
Post 15 Aug 2013, 12:39
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 15 Aug 2013, 14:21
VirtualAlloc is for allocation of large chunks of memory (> 64Kb).
Example: you need to scan very large file (say, 20Mb). You can try to
allocate with VirtualAlloc() these 20Mb and load the whole file into memory.
Or, you can create a buffer of say, 1Mb and read the file in pieces.

HeapAlloc is for allocation of small memory blocks - few bytes to few hundred bytes.
Internally HeapAlloc will use VirtualAlloc to increase its internal data structures and
then cut it to allocate smaller pieces.

===

Of course, you can use VirtualAlloc to allocate small blocks, but it would be a waste and you will
quickly fragment your program memory space.

Or you can use HeapAlloc to get larger pieces - it will still use VirtualAlloc inside it to get you that big piece.
Basically, you can use HeapAlloc for all your needs.

There is also something called FILE_FLAG_NO_BUFFERING.
It is a flag used to read file sectors directly into memory bypassing Windows file cache.
This improves performance, because Windows first will load the data into its own internal cache and then
transfer that data into your buffer. Using the flag will make just one transfer instead of two.

To use that flag you need to pass the buffer to ReadFile and that
buffer must be aligned on 4096 byte frame. Of course, it is possible to align it, but
VirtualAlloc will give you that ability without any special code -- any block
returned by that function is aligned on 4096 (or the page size for the Win OS you use).
Post 15 Aug 2013, 14:21
View user's profile Send private message Send e-mail Reply with quote
EaxRax



Joined: 20 Jul 2013
Posts: 15
EaxRax 15 Aug 2013, 15:34
AsmGuru62 wrote:
VirtualAlloc is for allocation of large chunks of memory (> 64Kb).
Example: you need to scan very large file (say, 20Mb). You can try to
allocate with VirtualAlloc() these 20Mb and load the whole file into memory.
Or, you can create a buffer of say, 1Mb and read the file in pieces.

HeapAlloc is for allocation of small memory blocks - few bytes to few hundred bytes.
Internally HeapAlloc will use VirtualAlloc to increase its internal data structures and
then cut it to allocate smaller pieces.

===

Of course, you can use VirtualAlloc to allocate small blocks, but it would be a waste and you will
quickly fragment your program memory space.

Or you can use HeapAlloc to get larger pieces - it will still use VirtualAlloc inside it to get you that big piece.
Basically, you can use HeapAlloc for all your needs.
Okey, thanks! Now all became a bit clearer!

The fact is that, I need to allocate a buffer for the file, whose size is not known in advance! Hence it appears that I need to use the VirtualAlloc?

AsmGuru62 wrote:
There is also something called FILE_FLAG_NO_BUFFERING.
It is a flag used to read file sectors directly into memory bypassing Windows file cache.
This improves performance, because Windows first will load the data into its own internal cache and then
transfer that data into your buffer. Using the flag will make just one transfer instead of two.

To use that flag you need to pass the buffer to ReadFile and that
buffer must be aligned on 4096 byte frame. Of course, it is possible to align it, but
VirtualAlloc will give you that ability without any special code -- any block
returned by that function is aligned on 4096 (or the page size for the Win OS you use).
Very interesting! Ladushki! Very Happy
Post 15 Aug 2013, 15:34
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 15 Aug 2013, 17:11
How is it that file size not known in advance?
GetFileSize() after CreateFile() and you know the size.

If you need to write the new file, then the size probably not known.
Then just get the buffer of 2Mb and write into that buffer in memory.
Once buffer is full - dump into file and empty buffer, preparing to fill it again.
But if you use FILE_FLAG_NO_BUFFERING - the file size will be aligned to 4096, so
there always be some zero bytes written at the end of data in the file.
In some cases OK (if you're making DB engine), but not in all cases (text file).
Post 15 Aug 2013, 17:11
View user's profile Send private message Send e-mail Reply with quote
EaxRax



Joined: 20 Jul 2013
Posts: 15
EaxRax 15 Aug 2013, 18:37
I see... But file in the buffer will be generated whenever the external data, so the file or the buffer size is not known in advance.
Post 15 Aug 2013, 18:37
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Aug 2013, 17:16
AsmGuru62 wrote:
To use that flag you need to pass the buffer to ReadFile and that buffer must be aligned on 4096 byte frame.

The actual requirement is "sector boundary" (both for memory alignment and read/write sizes).

I wonder if MS hasn't put in some compatibility shims since there's bound to be craploads of software that has hardcoded sector sizes as 512 bytes rather than querying the underlying storage device...

Don't think I have any 4k-sector disks around, though, so I can't test Smile

Also, wrt. the original question: use VirtualAlloc if you need large buffers, lots of alignment (don't depend on 64k, query the system information) or any of the advanced features VirtualAlloc can do.

If you need small buffers or need to alloc/dealloc often, prefer HeapAlloc. VirtualAlloc is relatively expensive, since it's going to kernelmode - HeapAlloc allocates large chunks and then allocates from that while staying in usermode, and is optimized for the usecase of smaller allocations.

_________________
Image - carpe noctem
Post 16 Aug 2013, 17:16
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.