How malloc() and free() Operate in Windows

ID: Q86841


The information in this article applies to:


SUMMARY

Using Microsoft C/C++ versions 7.0 and Visual C++ for Windows and the Windows C run-time library (SLIBCEW.LIB, for example), the functions malloc() and free() both make calls to the Windows API to allocate memory.

However, unlike earlier versions of malloc() and free(), the C/C++ 7.0 or newer version of these functions use a smart suballocation strategy, which both reduces the system-call overhead of these functions and makes them more efficient in their selector usage.

As a result of these enhancements, it is now possible to use the C/C++ 7.0 or newer version of malloc() and free() (or the C++ operators new and delete) for some simple memory allocations in your application designed for version 3.1 of the Microsoft Windows operating system.


MORE INFORMATION

The C run-time function "malloc" maps to either _fmalloc() (far malloc) or _nmalloc() (near malloc) depending on the ambient memory model. Because most Windows applications use far data, the following discussion will focus on the _fmalloc() function.

NOTE: This information on malloc also applies to C++ programming. In C/C++ version 7.0 and later, the C++ operator "new" calls the ambient memory model version of malloc [for example, in a large model C++ application, all calls to new end up calling _fmalloc() for the memory allocation].

The suballocation strategy used by _fmalloc() in C/C++ version 7.0 and later uses internal heap management to keep track of memory usage rather than allowing Windows to do it all.

Each time an application calls _fmalloc(), the run-time heap manager looks to see if it can satisfy the request within the segments that have already been allocated from Windows. If it can, the heap manager marks the block as used and returns a pointer to this memory (without calling any Windows memory allocation APIs). If not enough space exists, a new segment is allocated and linked in to the internal list of allocated segments.

In protected mode Windows, these new segments are allocated using GlobalAlloc(GMEM_MOVEABLE) for Windows applications and GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE) for Windows DLLs. The memory is then locked using GlobalLock(). When this segment finally needs to be freed, the GlobalUnlock() and GlobalFree() functions are used. [If using _nmalloc() under Windows, the functions LocalAlloc(), LocalLock(), LocalUnlock(), and LocalFree() are used for this process.]

One implication of using GMEM_DDESHARE for a DLL is that all _fmalloc() requests made by a DLL continue to exist for the lifetime of the DLL unless the application or DLL explicitly call _ffree(). If the application terminates abnormally, the DLL may remain in memory if it's dynamically linked to other applications. In this case, the memory allocated by _fmalloc() for the application is not freed as the application exits and remains allocated for the lifetime of the DLL.

Note that the Windows allocation flags used by malloc() and free() are hard-coded into the C run-time library and cannot be changed; therefore, if your program requires special flags (GMEM_NOTIFY, for example), you must use the standard Windows API to do the allocation.

One additional advantage of this internal heap management is that you will not get a new selector every time you call _fmalloc(). In earlier versions of the C run-time library for Windows, each call to _fmalloc() directly calls GlobalAlloc() and GlobalLock(), and a new selector is allocated for each call to _fmalloc(). Because all Windows applications share a limited number of selectors, it is best to minimize selector usage.

Additional query words: kbinf 7.00 1.00 1.50


Keywords          : kb16bitonly 
Version           : 
Platform          : 
Issue type        : 

Last Reviewed: August 5, 1999