GlobalAlloc || malloc

Started by
14 comments, last by Ethereal Darkness 22 years, 5 months ago
I have always ysed GlobalAlloc API to allocate memory, but... i have been thinking lately, whats the difference from the window''s memeory allocation and the C++ malloc? which is faster, and which is perferd?
Advertisement
I don''t know about speed differences, but malloc is portable. You might also want to find out about the ''new'' operator if you''re using C++.

All your bases belong to us (I know. It''s irony.)
CoV
Okay boys and girls, gather round the camp fire and let me tell you a story that will scare you $hitless.

Once upon a time intel CPU's where segmented (in fact they still are). Each segment was 64kb in size. So to access memory you needed two registers the Segment register and an other who's name escapes me for now.

So if you wanted to traverse a 64K boundary you needed to increment the segment register 256. Why 256 well the bottom 8 bits of the segment register addressed the same pages as the top 8 bits of the addressing register. 86/186/286 memory addressing is 24 bits.

Now enter Windows 3 into the fray. It used memory banking (NT still does but it does so under wraps). So to allocated memory so that the CPU would force the memory to be swapped into real memory if it was currently banked onto disk, you used GLobalAlloc and GlobalFree. If you used alloc() the memory pointer would return a block in Local Memory block. This was a local heap of memory that was 64kb in size. In fact if you wanted to allocate anything greater than 64K you needed to allocate it in powers of 2, i.e 128K, 256K, etc... Did I also mention that memory allocated had to be divisable by 2, and any memory address access was the same, read 'No odd address access'.

The up side of this memory scheme was that if you used a ;wild' memory ptr and then tried to access the address a GPF (General Protection Fault) would ensue. Great for tracking memory errors.

The advent of 32 bit registers in the 386 increased segment sizes to about 4GB.

So today there is no 'Global Memory' it is all 'Local' i.e. the heap is around 1GB.


I make no apologies for any inaccuracies in this post. I have tried very hard to forget what I once had to go through.



D.V.

Edited by - DeltaVee on November 13, 2001 2:49:35 PM
D.V.Carpe Diem
quote:Original post by DeltaVee
Okay boys and girls, gather round the camp fire and let me tell you a story that will scare you $hitless.

Didn''t scare me.
quote:
Once upon a time intel CPU''s where segmented (in fact they still are). Each segment was 64kb in size. So to access memory you needed two registers the Segment register and an other who''s name escapes me for now.

There were Index registers for the specific purpose of indexing memory, but you could also use the general purpose registers for the same.
quote:
The advent of 32 bit registers in the 386 increased segment sizes to about 4GB.

In actuality, it wasn''t just the registers that caused the increase in segment sizes. By default, even your top-of-the-line Pentium4 2Ghz monster starts up in 16-bit segmented mode. The major turning-point was the addition of ''protected-mode'', which was the mode the CPU had to be in in order for the flat memory model to be available.

All your bases belong to us (I know. It''s irony.)
CoV
quote:
I make no apologies for any inaccuracies in this post. I have tried very hard to forget what I once had to go through.


D.V.Carpe Diem
ok,
that was very informitive, thanks=)

but, im still wondering, what call should i use...
malloc, globalalloc, or virtualalloc?

Taking a gander throught the src for crtdll supplied with msvc - one sees that on windows malloc is a wrapper for HeapAlloc - using the prog''s 1 Mb default heap - don''t worry it will grow if it needs too.

I''m fairly certain that GlobalAlloc does the same. One way to check would be to use the ToolHelp API to examine the heap state after using each of the available mem allocators.

According to Jeffrey Richter''s "Advanced Windows" - HeapAlloc in turn wraps VirtualAlloc. I can''t confirm this because I don''t have the src for Kernel32 - (I wonder what they might be hiding...) - but it sounds reasonable. At any rate - for large memory allocations (16 Mb + ) use VirtualAlloc et al - or consider memory mapped files. For lots of little allocations, use malloc, GlobalAlloc, HeapAlloc as you want.


ok, thanks alot=)
seems kinda counterproductive to have so many functions that "alias" other ones...strange lol

All those function trace the development of computing history so to speak - you have DeltaVee''s explanation regarding segmented memory addresses to explain the difference betwee LocalAlloc and GlobalAlloc - they''re still around to provide backwards compatibility - we still want to give our old 16-bit windows progs a chance!

malloc is portable - so if you want to compile your src on Linux (etc) too - use malloc et al - including new and delete when appropriate.

On windows all memory is virtual - the kernel manages the hardware interface and dishes out memory as required. Even memory mapped files use virtual memory. My guess is that VirtualAlloc et al are the "true" memory funcs - but they are also more difficult to use - and thus the others come into play.

Say you''re just writing a quick console utility - having to write a full blown memory manager using VirtualAlloc etc would be quite a lot of work - so it''s much easier to use malloc, HeapAlloc or GlobalAlloc.
This is a general explanation - for more details find a copy of Richter''s book or check out comp.os.ms-windows.programmer.memory


If anyone is really intereted in how NT handles memory, I would higly recommend checking this out.
ReactOS - an Open-source operating system compatible with Windows NT apps and drivers

This topic is closed to new replies.

Advertisement