?? library_3.html
字號:
of the program's space is given back to the system when the process
terminates.
<P>
<A NAME="IDX146"></A>
<H3><A NAME="SEC25" HREF="library_toc.html#SEC25" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC25">Changing the Size of a Block</A></H3>
<P>
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.
<P>
You can make the block longer by calling <CODE>realloc</CODE>. This function
is declared in <TT>`stdlib.h'</TT>.
<A NAME="IDX147"></A>
<P>
<A NAME="IDX148"></A>
<U>Function:</U> void * <B>realloc</B> <I>(void *<VAR>ptr</VAR>, size_t <VAR>newsize</VAR>)</I><P>
The <CODE>realloc</CODE> function changes the size of the block whose address is
<VAR>ptr</VAR> to be <VAR>newsize</VAR>.
<P>
Since the space after the end of the block may be in use, <CODE>realloc</CODE>
may find it necessary to copy the block to a new address where more free
space is available. The value of <CODE>realloc</CODE> is the new address of the
block. If the block needs to be moved, <CODE>realloc</CODE> copies the old
contents.
<P>
Like <CODE>malloc</CODE>, <CODE>realloc</CODE> 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.
<P>
In most cases it makes no difference what happens to the original block
when <CODE>realloc</CODE> 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</CODE>, that takes care of the error message
as <CODE>xmalloc</CODE> does for <CODE>malloc</CODE>:
<P>
<PRE>
void *
xrealloc (void *ptr, size_t size)
{
register void *value = realloc (ptr, size);
if (value == 0)
fatal ("Virtual memory exhausted");
return value;
}
</PRE>
<P>
You can also use <CODE>realloc</CODE> 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.
<P>
If the new size you specify is the same as the old size, <CODE>realloc</CODE>
is guaranteed to change nothing and return the same address that you gave.
<P>
<H3><A NAME="SEC26" HREF="library_toc.html#SEC26" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC26">Allocating Cleared Space</A></H3>
<P>
The function <CODE>calloc</CODE> allocates memory and clears it to zero. It
is declared in <TT>`stdlib.h'</TT>.
<A NAME="IDX149"></A>
<P>
<A NAME="IDX150"></A>
<U>Function:</U> void * <B>calloc</B> <I>(size_t <VAR>count</VAR>, size_t <VAR>eltsize</VAR>)</I><P>
This function allocates a block long enough to contain a vector of
<VAR>count</VAR> elements, each of size <VAR>eltsize</VAR>. Its contents are
cleared to zero before <CODE>calloc</CODE> returns.
<P>
You could define <CODE>calloc</CODE> as follows:
<P>
<PRE>
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;
}
</PRE>
<P>
We rarely use <CODE>calloc</CODE> today, because it is equivalent to such a
simple combination of other features that are more often used. It is a
historical holdover that is not quite obsolete.
<P>
<A NAME="IDX151"></A>
<H3><A NAME="SEC27" HREF="library_toc.html#SEC27" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC27">Efficiency Considerations for <CODE>malloc</CODE></A></H3>
<P>
To make the best use of <CODE>malloc</CODE>, it helps to know that the GNU
version of <CODE>malloc</CODE> 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</CODE> more efficient, make it a power of two.
<P>
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.
<P>
When you ask for memory blocks of a page or larger, <CODE>malloc</CODE> uses a
different strategy; it rounds the size up to a multiple of a page, and
it can coalesce and split blocks as needed.
<P>
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.
<P>
<H3><A NAME="SEC28" HREF="library_toc.html#SEC28" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC28">Allocating Aligned Memory Blocks</A></H3>
<A NAME="IDX152"></A>
<A NAME="IDX153"></A>
<A NAME="IDX154"></A>
<P>
The address of a block returned by <CODE>malloc</CODE> or <CODE>realloc</CODE> 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</CODE> or <CODE>valloc</CODE>. These functions are declared in
<TT>`stdlib.h'</TT>.
<P>
With the GNU library, you can use <CODE>free</CODE> to free the blocks that
<CODE>memalign</CODE> and <CODE>valloc</CODE> return. That does not work in BSD,
however--BSD does not provide any way to free such blocks.
<P>
<A NAME="IDX155"></A>
<U>Function:</U> void * <B>memalign</B> <I>(size_t <VAR>size</VAR>, int <VAR>boundary</VAR>)</I><P>
The <CODE>memalign</CODE> function allocates a block of <VAR>size</VAR> bytes whose
address is a multiple of <VAR>boundary</VAR>. The <VAR>boundary</VAR> must be a
power of two! The function <CODE>memalign</CODE> works by calling
<CODE>malloc</CODE> to allocate a somewhat larger block, and then returning an
address within the block that is on the specified boundary.
<P>
<A NAME="IDX156"></A>
<U>Function:</U> void * <B>valloc</B> <I>(size_t <VAR>size</VAR>)</I><P>
Using <CODE>valloc</CODE> is like using <CODE>memalign</CODE> and passing the page size
as the value of the second argument.
<P>
<H3><A NAME="SEC29" HREF="library_toc.html#SEC29" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC29">Heap Consistency Checking</A></H3>
<A NAME="IDX157"></A>
<A NAME="IDX158"></A>
<P>
You can ask <CODE>malloc</CODE> to check the consistency of dynamic storage by
using the <CODE>mcheck</CODE> function. This function is a GNU extension,
declared in <TT>`malloc.h'</TT>.
<A NAME="IDX159"></A>
<P>
<A NAME="IDX160"></A>
<U>Function:</U> void <B>mcheck</B> <I>(void (*<VAR>abortfn</VAR>) (void))</I><P>
Calling <CODE>mcheck</CODE> tells <CODE>malloc</CODE> to perform occasional
consistency checks. These will catch things such as writing
past the end of a block that was allocated with <CODE>malloc</CODE>.
<P>
The <VAR>abortfn</VAR> argument is the function to call when an inconsistency
is found. If you supply a null pointer, the <CODE>abort</CODE> function is
used.
<P>
It is too late to begin allocation checking once you have allocated
anything with <CODE>malloc</CODE>. So <CODE>mcheck</CODE> does nothing in that
case. The function returns <CODE>-1</CODE> if you call it too late, and
<CODE>0</CODE> otherwise (when it is successful).
<P>
The easiest way to arrange to call <CODE>mcheck</CODE> early enough is to use
the option <SAMP>`-lmcheck'</SAMP> when you link your program.
<P>
<A NAME="IDX161"></A>
<H3><A NAME="SEC30" HREF="library_toc.html#SEC30" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC30">Storage Allocation Hooks</A></H3>
<P>
The GNU C library lets you modify the behavior of <CODE>malloc</CODE>,
<CODE>realloc</CODE>, and <CODE>free</CODE> by specifying appropriate hook
functions. You can use these hooks to help you debug programs that use
dynamic storage allocation, for example.
<P>
The hook variables are declared in <TT>`malloc.h'</TT>.
<A NAME="IDX162"></A>
<P>
<A NAME="IDX163"></A>
<U>Variable:</U> <B>__malloc_hook</B><P>
The value of this variable is a pointer to function that <CODE>malloc</CODE>
uses whenever it is called. You should define this function to look
like <CODE>malloc</CODE>; that is, like:
<P>
<PRE>
void *<VAR>function</VAR> (size_t <VAR>size</VAR>)
</PRE>
<P>
<A NAME="IDX164"></A>
<U>Variable:</U> <B>__realloc_hook</B><P>
The value of this variable is a pointer to function that <CODE>realloc</CODE>
uses whenever it is called. You should define this function to look
like <CODE>realloc</CODE>; that is, like:
<P>
<PRE>
void *<VAR>function</VAR> (void *<VAR>ptr</VAR>, size_t <VAR>size</VAR>)
</PRE>
<P>
<A NAME="IDX165"></A>
<U>Variable:</U> <B>__free_hook</B><P>
The value of this variable is a pointer to function that <CODE>free</CODE>
uses whenever it is called. You should define this function to look
like <CODE>free</CODE>; that is, like:
<P>
<PRE>
void <VAR>function</VAR> (void *<VAR>ptr</VAR>)
</PRE>
<P>
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.
<P>
Here is an example showing how to use <CODE>__malloc_hook</CODE> properly. It
installs a function that prints out information every time <CODE>malloc</CODE>
is called.
<P>
<PRE>
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);
__malloc_hook = my_malloc_hook;
printf ("malloc (%u) returns %p\n", (unsigned int) size, result);
return result;
}
main ()
{
...
old_malloc_hook = __malloc_hook;
__malloc_hook = my_malloc_hook;
...
}
</PRE>
<P>
The <CODE>mcheck</CODE> function (see section <A HREF="library_3.html#SEC29" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC29">Heap Consistency Checking</A>) works by
installing such hooks.
<P>
<H3><A NAME="SEC31" HREF="library_toc.html#SEC31" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC31">Statistics for Storage Allocation with <CODE>malloc</CODE></A></H3>
<A NAME="IDX166"></A>
<P>
You can get information about dynamic storage allocation by calling the
<CODE>mstats</CODE> function. This function and its associated data type are
declared in <TT>`malloc.h'</TT>; they are a GNU extension.
<A NAME="IDX167"></A>
<P>
<A NAME="IDX168"></A>
<U>Data Type:</U> <B>struct mstats</B><P>
This structure type is used to return information about the dynamic
storage allocator. It contains the following members:
<P>
<DL COMPACT>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -