diff options
| author | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
|---|---|---|
| committer | Roland McGrath <roland@gnu.org> | 1995-02-18 01:27:10 +0000 |
| commit | 28f540f45bbacd939bfd07f213bcad2bf730b1bf (patch) | |
| tree | 15f07c4c43d635959c6afee96bde71fb1b3614ee /manual/memory.texi | |
| download | glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.tar.xz glibc-28f540f45bbacd939bfd07f213bcad2bf730b1bf.zip | |
initial import
Diffstat (limited to 'manual/memory.texi')
| -rw-r--r-- | manual/memory.texi | 1751 |
1 files changed, 1751 insertions, 0 deletions
diff --git a/manual/memory.texi b/manual/memory.texi new file mode 100644 index 0000000000..9269380e1d --- /dev/null +++ b/manual/memory.texi @@ -0,0 +1,1751 @@ +@comment !!! describe mmap et al (here?) +@c !!! doc brk/sbrk + +@node Memory Allocation, Character Handling, Error Reporting, Top +@chapter Memory Allocation +@cindex memory allocation +@cindex storage allocation + +The GNU system provides several methods for allocating memory space +under explicit program control. They vary in generality and in +efficiency. + +@iftex +@itemize @bullet +@item +The @code{malloc} facility allows fully general dynamic allocation. +@xref{Unconstrained Allocation}. + +@item +Obstacks are another facility, less general than @code{malloc} but more +efficient and convenient for stacklike allocation. @xref{Obstacks}. + +@item +The function @code{alloca} lets you allocate storage dynamically that +will be freed automatically. @xref{Variable Size Automatic}. +@end itemize +@end iftex + +@menu +* Memory Concepts:: An introduction to concepts and terminology. +* Dynamic Allocation and C:: How to get different kinds of allocation in C. +* Unconstrained Allocation:: The @code{malloc} facility allows fully general + dynamic allocation. +* Obstacks:: Obstacks are less general than malloc + but more efficient and convenient. +* Variable Size Automatic:: Allocation of variable-sized blocks + of automatic storage that are freed when the + calling function returns. +* Relocating Allocator:: Waste less memory, if you can tolerate + automatic relocation of the blocks you get. +* Memory Warnings:: Getting warnings when memory is nearly full. +@end menu + +@node Memory Concepts +@section Dynamic Memory Allocation Concepts +@cindex dynamic allocation +@cindex static allocation +@cindex automatic allocation + +@dfn{Dynamic memory allocation} is a technique in which programs +determine as they are running where to store some information. You need +dynamic allocation when the number of memory blocks you need, or how +long you continue to need them, depends on the data you are working on. + +For example, you may need a block to store a line read from an input file; +since there is no limit to how long a line can be, you must allocate the +storage dynamically and make it dynamically larger as you read more of the +line. + +Or, you may need a block for each record or each definition in the input +data; since you can't know in advance how many there will be, you must +allocate a new block for each record or definition as you read it. + +When you use dynamic allocation, the allocation of a block of memory is an +action that the program requests explicitly. You call a function or macro +when you want to allocate space, and specify the size with an argument. If +you want to free the space, you do so by calling another function or macro. +You can do these things whenever you want, as often as you want. + +@node Dynamic Allocation and C +@section Dynamic Allocation and C + +The C language supports two kinds of memory allocation through the variables +in C programs: + +@itemize @bullet +@item +@dfn{Static allocation} is what happens when you declare a static or +global variable. Each static or global variable defines one block of +space, of a fixed size. The space is allocated once, when your program +is started, and is never freed. + +@item +@dfn{Automatic allocation} happens when you declare an automatic +variable, such as a function argument or a local variable. The space +for an automatic variable is allocated when the compound statement +containing the declaration is entered, and is freed when that +compound statement is exited. + +In GNU C, the length of the automatic storage can be an expression +that varies. In other C implementations, it must be a constant. +@end itemize + +Dynamic allocation is not supported by C variables; there is no storage +class ``dynamic'', and there can never be a C variable whose value is +stored in dynamically allocated space. The only way to refer to +dynamically allocated space is through a pointer. Because it is less +convenient, and because the actual process of dynamic allocation +requires more computation time, programmers generally use dynamic +allocation only when neither static nor automatic allocation will serve. + +For example, if you want to allocate dynamically some space to hold a +@code{struct foobar}, you cannot declare a variable of type @code{struct +foobar} whose contents are the dynamically allocated space. But you can +declare a variable of pointer type @code{struct foobar *} and assign it the +address of the space. Then you can use the operators @samp{*} and +@samp{->} on this pointer variable to refer to the contents of the space: + +@smallexample +@{ + struct foobar *ptr + = (struct foobar *) malloc (sizeof (struct foobar)); + ptr->name = x; + ptr->next = current_foobar; + current_foobar = ptr; +@} +@end smallexample + +@node Unconstrained Allocation +@section Unconstrained Allocation +@cindex unconstrained storage allocation +@cindex @code{malloc} function +@cindex heap, dynamic allocation from + +The most general dynamic allocation facility is @code{malloc}. It +allows you to allocate blocks of memory of any size at any time, make +them bigger or smaller at any time, and free the blocks individually at +any time (or never). + +@menu +* Basic Allocation:: Simple use of @code{malloc}. +* Malloc Examples:: Examples of @code{malloc}. @code{xmalloc}. +* Freeing after Malloc:: Use @code{free} to free a block you + got with @code{malloc}. +* Changing Block Size:: Use @code{realloc} to make a block + bigger or smaller. +* Allocating Cleared Space:: Use @code{calloc} to allocate a + block and clear it. +* Efficiency and Malloc:: Efficiency considerations in use of + these functions. +* Aligned Memory Blocks:: Allocating specially aligned memory: + @code{memalign} and @code{valloc}. +* Heap Consistency Checking:: Automatic checking for errors. +* Hooks for Malloc:: You can use these hooks for debugging + programs that use @code{malloc}. +* Statistics of Malloc:: Getting information about how much + memory your program is using. +* Summary of Malloc:: Summary of @code{malloc} and related functions. +@end menu + +@node Basic Allocation +@subsection Basic Storage Allocation +@cindex allocation of memory with @code{malloc} + +To allocate a block of memory, call @code{malloc}. The prototype for +this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} malloc (size_t @var{size}) +This function returns a pointer to a newly allocated block @var{size} +bytes long, or a null pointer if the block could not be allocated. +@end deftypefun + +The contents of the block are undefined; you must initialize it yourself +(or use @code{calloc} instead; @pxref{Allocating Cleared Space}). +Normally you would cast the value as a pointer to the kind of object +that you want to store in the block. Here we show an example of doing +so, and of initializing the space with zeros using the library function +@code{memset} (@pxref{Copying and Concatenation}): + +@smallexample +struct foo *ptr; +@dots{} +ptr = (struct foo *) malloc (sizeof (struct foo)); +if (ptr == 0) abort (); +memset (ptr, 0, sizeof (struct foo)); +@end smallexample + +You can store the result of @code{malloc} into any pointer variable +without a cast, because ANSI C automatically converts the type +@code{void *} to another type of pointer when necessary. But the cast +is necessary in contexts other than assignment operators or if you might +want your code to run in traditional C. + +Remember that when allocating space for a string, the argument to +@code{malloc} must be one plus the length of the string. This is +because a string is terminated with a null character that doesn't count +in the ``length'' of the string but does need space. For example: + +@smallexample +char *ptr; +@dots{} +ptr = (char *) malloc (length + 1); +@end smallexample + +@noindent +@xref{Representation of Strings}, for more information about this. + +@node Malloc Examples +@subsection Examples of @code{malloc} + +If no more space is available, @code{malloc} returns a null pointer. +You should check the value of @emph{every} call to @code{malloc}. It is +useful to write a subroutine that calls @code{malloc} and reports an +error if the value is a null pointer, returning only if the value is +nonzero. This function is conventionally called @code{xmalloc}. Here +it is: + +@smallexample +void * +xmalloc (size_t size) +@{ + register void *value = malloc (size); + if (value == 0) + fatal ("virtual memory exhausted"); + return value; +@} +@end smallexample + +Here is a real example of using @code{malloc} (by way of @code{xmalloc}). +The function @code{savestring} will copy a sequence of characters into +a newly allocated null-terminated string: + +@smallexample +@group +char * +savestring (const char *ptr, size_t len) +@{ + register char *value = (char *) xmalloc (len + 1); + memcpy (value, ptr, len); + value[len] = '\0'; + return value; +@} +@end group +@end smallexample + +The block that @code{malloc} gives you is guaranteed to be aligned so +that it can hold any type of data. In the GNU system, the address is +always a multiple of eight; if the size of block is 16 or more, then the +address is always a multiple of 16. Only rarely is any higher boundary +(such as a page boundary) necessary; for those cases, use +@code{memalign} or @code{valloc} (@pxref{Aligned Memory Blocks}). + +Note that the memory located after the end of the block is likely to be +in use for something else; perhaps a block already allocated by another +call to @code{malloc}. If you attempt to treat the block as longer than +you asked for it to be, you are liable to destroy the data that +@code{malloc} uses to keep track of its blocks, or you may destroy the +contents of another block. If you have already allocated a block and +discover you want it to be bigger, use @code{realloc} (@pxref{Changing +Block Size}). + +@node Freeing after Malloc +@subsection Freeing Memory Allocated with @code{malloc} +@cindex freeing memory allocated with @code{malloc} +@cindex heap, freeing memory from + +When you no longer need a block that you got with @code{malloc}, use the +function @code{free} to make the block available to be allocated again. +The prototype for this function is in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun void free (void *@var{ptr}) +The @code{free} function deallocates the block of storage pointed at +by @var{ptr}. +@end deftypefun + +@comment stdlib.h +@comment Sun +@deftypefun void cfree (void *@var{ptr}) +This function does the same thing as @code{free}. It's provided for +backward compatibility with SunOS; you should use @code{free} instead. +@end deftypefun + +Freeing a block alters the contents of the block. @strong{Do not expect to +find any data (such as a pointer to the next block in a chain of blocks) in +the block after freeing it.} Copy whatever you need out of the block before +freeing it! Here is an example of the proper way to free all the blocks in +a chain, and the strings that they point to: + +@smallexample +struct chain + @{ + struct chain *next; + char *name; + @} + +void +free_chain (struct chain *chain) +@{ + while (chain != 0) + @{ + struct chain *next = chain->next; + free (chain->name); + free (chain); + chain = next; + @} +@} +@end smallexample + +Occasionally, @code{free} can actually return memory to the operating +system and make the process smaller. Usually, all it can do is allow a +later call to @code{malloc} to reuse the space. In the meantime, the +space remains in your program as part of a free-list used internally by +@code{malloc}. + +There is no point in freeing blocks at the end of a program, because all +of the program's space is given back to the system when the process +terminates. + +@node Changing Block Size +@subsection Changing the Size of a Block +@cindex changing the size of a block (@code{malloc}) + +Often you do not know for certain how big a block you will ultimately need +at the time you must begin to use the block. For example, the block might +be a buffer that you use to hold a line being read from a file; no matter +how long you make the buffer initially, you may encounter a line that is +longer. + +You can make the block longer by calling @code{realloc}. This function +is declared in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize}) +The @code{realloc} function changes the size of the block whose address is +@var{ptr} to be @var{newsize}. + +Since the space after the end of the block may be in use, @code{realloc} +may find it necessary to copy the block to a new address where more free +space is available. The value of @code{realloc} is the new address of the +block. If the block needs to be moved, @code{realloc} copies the old +contents. + +If you pass a null pointer for @var{ptr}, @code{realloc} behaves just +like @samp{malloc (@var{newsize})}. This can be convenient, but beware +that older implementations (before ANSI C) may not support this +behavior, and will probably crash when @code{realloc} is passed a null +pointer. +@end deftypefun + +Like @code{malloc}, @code{realloc} may return a null pointer if no +memory space is available to make the block bigger. When this happens, +the original block is untouched; it has not been modified or relocated. + +In most cases it makes no difference what happens to the original block +when @code{realloc} fails, because the application program cannot continue +when it is out of memory, and the only thing to do is to give a fatal error +message. Often it is convenient to write and use a subroutine, +conventionally called @code{xrealloc}, that takes care of the error message +as @code{xmalloc} does for @code{malloc}: + +@smallexample +void * +xrealloc (void *ptr, size_t size) +@{ + register void *value = realloc (ptr, size); + if (value == 0) + fatal ("Virtual memory exhausted"); + return value; +@} +@end smallexample + +You can also use @code{realloc} to make a block smaller. The reason you +would do this is to avoid tying up a lot of memory space when only a little +is needed. Making a block smaller sometimes necessitates copying it, so it +can fail if no other space is available. + +If the new size you specify is the same as the old size, @code{realloc} +is guaranteed to change nothing and return the same address that you gave. + +@node Allocating Cleared Space +@subsection Allocating Cleared Space + +The function @code{calloc} allocates memory and clears it to zero. It +is declared in @file{stdlib.h}. +@pindex stdlib.h + +@comment malloc.h stdlib.h +@comment ANSI +@deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize}) +This function allocates a block long enough to contain a vector of +@var{count} elements, each of size @var{eltsize}. Its contents are +cleared to zero before @code{calloc} returns. +@end deftypefun + +You could define @code{calloc} as follows: + +@smallexample +void * +calloc (size_t count, size_t eltsize) +@{ + size_t size = count * eltsize; + void *value = malloc (size); + if (value != 0) + memset (value, 0, size); + return value; +@} +@end smallexample + +@node Efficiency and Malloc +@subsection Efficiency Considerations for @code{malloc} +@cindex efficiency and @code{malloc} + +To make the best use of @code{malloc}, it helps to know that the GNU +version of @code{malloc} always dispenses small amounts of memory in +blocks whose sizes are powers of two. It keeps separate pools for each +power of two. This holds for sizes up to a page size. Therefore, if +you are free to choose the size of a small block in order to make +@code{malloc} more efficient, make it a power of two. +@c !!! xref getpagesize + +Once a page is split up for a particular block size, it can't be reused +for another size unless all the blocks in it are freed. In many +programs, this is unlikely to happen. Thus, you can sometimes make a +program use memory more efficiently by using blocks of the same size for +many different purposes. + +When you ask for memory blocks of a page or larger, @code{malloc} uses a +different strategy; it rounds the size up to a multiple of a page, and +it can coalesce and split blocks as needed. + +The reason for the two strategies is that it is important to allocate +and free small blocks as fast as possible, but speed is less important +for a large block since the program normally spends a fair amount of +time using it. Also, large blocks are normally fewer in number. +Therefore, for large blocks, it makes sense to use a method which takes +more time to minimize the wasted space. + +@node Aligned Memory Blocks +@subsection Allocating Aligned Memory Blocks + +@cindex page boundary +@cindex alignment (with @code{malloc}) +@pindex stdlib.h +The address of a block returned by @code{malloc} or @code{realloc} in +the GNU system is always a multiple of eight. If you need a block whose +address is a multiple of a higher power of two than that, use +@code{memalign} or @code{valloc}. These functions are declared in +@file{stdlib.h}. + +With the GNU library, you can use @code{free} to free the blocks that +@code{memalign} and @code{valloc} return. That does not work in BSD, +however---BSD does not provide any way to free such blocks. + +@comment malloc.h stdlib.h +@comment BSD +@deftypefun {void *} memalign (size_t @var{size}, size_t @var{boundary}) +The @code{memalign} function allocates a block of @var{size} bytes whose +address is a multiple of @var{boundary}. The @var{boundary} must be a +power of two! The function @code{memalign} works by calling +@code{malloc} to allocate a somewhat larger block, and then returning an +address within the block that is on the specified boundary. +@end deftypefun + +@comment malloc.h stdlib.h +@comment BSD +@deftypefun {void *} valloc (size_t @var{size}) +Using @code{valloc} is like using @code{memalign} and passing the page size +as the value of the second argument. It is implemented like this: + +@smallexample +void * +valloc (size_t size) +@{ + return memalign (size, getpagesize ()); +@} +@end smallexample +@c !!! xref getpagesize +@end deftypefun + +@node Heap Consistency Checking +@subsection Heap Consistency Checking + +@cindex heap consistency checking +@cindex consistency checking, of heap + +You can ask @code{malloc} to check the consistency of dynamic storage by +using the @code{mcheck} function. This function is a GNU extension, +declared in @file{malloc.h}. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status})) +Calling @code{mcheck} tells @code{malloc} to perform occasional +consistency checks. These will catch things such as writing +past the end of a block that was allocated with @code{malloc}. + +The @var{abortfn} argument is the function to call when an inconsistency +is found. If you supply a null pointer, then @code{mcheck} uses a +default function which prints a message and calls @code{abort} +(@pxref{Aborting a Program}). The function you supply is called with +one argument, which says what sort of inconsistency was detected; its +type is described below. + +It is too late to begin allocation checking once you have allocated +anything with @code{malloc}. So @code{mcheck} does nothing in that +case. The function returns @code{-1} if you call it too late, and +@code{0} otherwise (when it is successful). + +The easiest way to arrange to call @code{mcheck} early enough is to use +the option @samp{-lmcheck} when you link your program; then you don't +need to modify your program source at all. +@end deftypefun + +@deftypefun {enum mcheck_status} mprobe (void *@var{pointer}) +The @code{mprobe} function lets you explicitly check for inconsistencies +in a particular allocated block. You must have already called +@code{mcheck} at the beginning of the program, to do its occasional +checks; calling @code{mprobe} requests an additional consistency check +to be done at the time of the call. + +The argument @var{pointer} must be a pointer returned by @code{malloc} +or @code{realloc}. @code{mprobe} returns a value that says what +inconsistency, if any, was found. The values are described below. +@end deftypefun + +@deftp {Data Type} {enum mcheck_status} +This enumerated type describes what kind of inconsistency was detected +in an allocated block, if any. Here are the possible values: + +@table @code +@item MCHECK_DISABLED +@code{mcheck} was not called before the first allocation. +No consistency checking can be done. +@item MCHECK_OK +No inconsistency detected. +@item MCHECK_HEAD +The data immediately before the block was modified. +This commonly happens when an array index or pointer +is decremented too far. +@item MCHECK_TAIL +The data immediately after the block was modified. +This commonly happens when an array index or pointer +is incremented too far. +@item MCHECK_FREE +The block was already freed. +@end table +@end deftp + +@node Hooks for Malloc +@subsection Storage Allocation Hooks +@cindex allocation hooks, for @code{malloc} + +The GNU C library lets you modify the behavior of @code{malloc}, +@code{realloc}, and @code{free} by specifying appropriate hook +functions. You can use these hooks to help you debug programs that use +dynamic storage allocation, for example. + +The hook variables are declared in @file{malloc.h}. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@defvar __malloc_hook +The value of this variable is a pointer to function that @code{malloc} +uses whenever it is called. You should define this function to look +like @code{malloc}; that is, like: + +@smallexample +void *@var{function} (size_t @var{size}) +@end smallexample +@end defvar + +@comment malloc.h +@comment GNU +@defvar __realloc_hook +The value of this variable is a pointer to function that @code{realloc} +uses whenever it is called. You should define this function to look +like @code{realloc}; that is, like: + +@smallexample +void *@var{function} (void *@var{ptr}, size_t @var{size}) +@end smallexample +@end defvar + +@comment malloc.h +@comment GNU +@defvar __free_hook +The value of this variable is a pointer to function that @code{free} +uses whenever it is called. You should define this function to look +like @code{free}; that is, like: + +@smallexample +void @var{function} (void *@var{ptr}) +@end smallexample +@end defvar + +You must make sure that the function you install as a hook for one of +these functions does not call that function recursively without restoring +the old value of the hook first! Otherwise, your program will get stuck +in an infinite recursion. + +Here is an example showing how to use @code{__malloc_hook} properly. It +installs a function that prints out information every time @code{malloc} +is called. + +@smallexample +static void *(*old_malloc_hook) (size_t); +static void * +my_malloc_hook (size_t size) +@{ + void *result; + __malloc_hook = old_malloc_hook; + result = malloc (size); + /* @r{@code{printf} might call @code{malloc}, so protect it too.} */ + printf ("malloc (%u) returns %p\n", (unsigned int) size, result); + __malloc_hook = my_malloc_hook; + return result; +@} + +main () +@{ + ... + old_malloc_hook = __malloc_hook; + __malloc_hook = my_malloc_hook; + ... +@} +@end smallexample + +The @code{mcheck} function (@pxref{Heap Consistency Checking}) works by +installing such hooks. + +@c __morecore, __after_morecore_hook are undocumented +@c It's not clear whether to document them. + +@node Statistics of Malloc +@subsection Statistics for Storage Allocation with @code{malloc} + +@cindex allocation statistics +You can get information about dynamic storage allocation by calling the +@code{mstats} function. This function and its associated data type are +declared in @file{malloc.h}; they are a GNU extension. +@pindex malloc.h + +@comment malloc.h +@comment GNU +@deftp {Data Type} {struct mstats} +This structure type is used to return information about the dynamic +storage allocator. It contains the following members: + +@table @code +@item size_t bytes_total +This is the total size of memory managed by @code{malloc}, in bytes. + +@item size_t chunks_used +This is the number of chunks in use. (The storage a |
