How malloc() and free() Operate in WindowsID: Q86841
|
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.
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