?? library_3.html
字號(hào):
<P>
<PRE>
obstack_free (obstack_ptr, first_object_allocated_ptr);
</PRE>
<P>
Recall that the objects in an obstack are grouped into chunks. When all
the objects in a chunk become free, the obstack library automatically
frees the chunk (see section <A HREF="library_3.html#SEC35" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC35">Preparing for Using Obstacks</A>). Then other
obstacks, or non-obstack allocation, can reuse the space of the chunk.
<P>
<A NAME="IDX182"></A>
<H3><A NAME="SEC38" HREF="library_toc.html#SEC38" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC38">Obstack Functions and Macros</A></H3>
<P>
The interfaces for using obstacks may be defined either as functions or
as macros, depending on the compiler. The obstack facility works with
all C compilers, including both ANSI C and traditional C, but there are
precautions you must take if you plan to use compilers other than GNU C.
<P>
If you are using an old-fashioned non-ANSI C compiler, all the obstack
"functions" are actually defined only as macros. You can call these
macros like functions, but you cannot use them in any other way (for
example, you cannot take their address).
<P>
Calling the macros requires a special precaution: namely, the first
operand (the obstack pointer) may not contain any side effects, because
it may be computed more than once. For example, if you write this:
<P>
<PRE>
obstack_alloc (get_obstack (), 4);
</PRE>
<P>
you will find that <CODE>get_obstack</CODE> may be called several times.
If you use <CODE>*obstack_list_ptr++</CODE> as the obstack pointer argument,
you will get very strange results since the incrementation may occur
several times.
<P>
In ANSI C, each function has both a macro definition and a function
definition. The function definition is used if you take the address of the
function without calling it. An ordinary call uses the macro definition by
default, but you can request the function definition instead by writing the
function name in parentheses, as shown here:
<P>
<PRE>
char *x;
void *(*funcp) ();
/* Use the macro. */
x = (char *) obstack_alloc (obptr, size);
/* Call the function. */
x = (char *) (obstack_alloc) (obptr, size);
/* Take the address of the function. */
funcp = obstack_alloc;
</PRE>
<P>
This is the same situation that exists in ANSI C for the standard library
functions. See section <A HREF="library_1.html#SEC10" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_1.html#SEC10">Macro Definitions of Functions</A>.
<P>
<STRONG>Warning:</STRONG> When you do use the macros, you must observe the
precaution of avoiding side effects in the first operand, even in ANSI
C.
<P>
If you use the GNU C compiler, this precaution is not necessary, because
various language extensions in GNU C permit defining the macros so as to
compute each argument only once.
<P>
<A NAME="IDX183"></A>
<A NAME="IDX184"></A>
<H3><A NAME="SEC39" HREF="library_toc.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC39">Growing Objects</A></H3>
<P>
Because storage in obstack chunks is used sequentially, it is possible to
build up an object step by step, adding one or more bytes at a time to the
end of the object. With this technique, you do not need to know how much
data you will put in the object until you come to the end of it. We call
this the technique of <DFN>growing objects</DFN>. The special functions
for adding data to the growing object are described in this section.
<P>
You don't need to do anything special when you start to grow an object.
Using one of the functions to add data to the object automatically
starts it. However, it is necessary to say explicitly when the object is
finished. This is done with the function <CODE>obstack_finish</CODE>.
<P>
The actual address of the object thus built up is not known until the
object is finished. Until then, it always remains possible that you will
add so much data that the object must be copied into a new chunk.
<P>
While the obstack is in use for a growing object, you cannot use it for
ordinary allocation of another object. If you try to do so, the space
already added to the growing object will become part of the other object.
<P>
<A NAME="IDX185"></A>
<U>Function:</U> void <B>obstack_blank</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, size_t <VAR>size</VAR>)</I><P>
The most basic function for adding to a growing object is
<CODE>obstack_blank</CODE>, which adds space without initializing it.
<P>
<A NAME="IDX186"></A>
<U>Function:</U> void <B>obstack_grow</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>data</VAR>, size_t <VAR>size</VAR>)</I><P>
To add a block of initialized space, use <CODE>obstack_grow</CODE>, which is
the growing-object analogue of <CODE>obstack_copy</CODE>. It adds <VAR>size</VAR>
bytes of data to the growing object, copying the contents from
<VAR>data</VAR>.
<P>
<A NAME="IDX187"></A>
<U>Function:</U> void <B>obstack_grow0</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>data</VAR>, size_t <VAR>size</VAR>)</I><P>
This is the growing-object analogue of <CODE>obstack_copy0</CODE>. It adds
<VAR>size</VAR> bytes copied from <VAR>data</VAR>, followed by an additional null
character.
<P>
<A NAME="IDX188"></A>
<U>Function:</U> void <B>obstack_1grow</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, char <VAR>c</VAR>)</I><P>
To add one character at a time, use the function <CODE>obstack_1grow</CODE>.
It adds a single byte containing <VAR>c</VAR> to the growing object.
<P>
<A NAME="IDX189"></A>
<U>Function:</U> void * <B>obstack_finish</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
When you are finished growing the object, use the function
<CODE>obstack_finish</CODE> to close it off and return its final address.
<P>
Once you have finished the object, the obstack is available for ordinary
allocation or for growing another object.
<P>
When you build an object by growing it, you will probably need to know
afterward how long it became. You need not keep track of this as you grow
the object, because you can find out the length from the obstack just
before finishing the object with the function <CODE>obstack_object_size</CODE>,
declared as follows:
<P>
<A NAME="IDX190"></A>
<U>Function:</U> size_t <B>obstack_object_size</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
This function returns the current size of the growing object, in bytes.
Remember to call this function <EM>before</EM> finishing the object.
After it is finished, <CODE>obstack_object_size</CODE> will return zero.
<P>
If you have started growing an object and wish to cancel it, you should
finish it and then free it, like this:
<P>
<PRE>
obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
</PRE>
<P>
This has no effect if no object was growing.
<A NAME="IDX191"></A>
<P>
You can use <CODE>obstack_blank</CODE> with a negative size argument to make
the current object smaller. Just don't try to shrink it beyond zero
length--there's no telling what will happen if you do that.
<P>
<A NAME="IDX192"></A>
<H3><A NAME="SEC40" HREF="library_toc.html#SEC40" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC40">Extra Fast Growing Objects</A></H3>
<P>
The usual functions for growing objects incur overhead for checking
whether there is room for the new growth in the current chunk. If you
are frequently constructing objects in small steps of growth, this
overhead can be significant.
<P>
You can reduce the overhead by using special "fast growth"
functions that grow the object without checking. In order to have a
robust program, you must do the checking yourself. If you do this checking
in the simplest way each time you are about to add data to the object, you
have not saved anything, because that is what the ordinary growth
functions do. But if you can arrange to check less often, or check
more efficiently, then you make the program faster.
<P>
The function <CODE>obstack_room</CODE> returns the amount of room available
in the current chunk. It is declared as follows:
<P>
<A NAME="IDX193"></A>
<U>Function:</U> size_t <B>obstack_room</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
This returns the number of bytes that can be added safely to the current
growing object (or to an object about to be started) in obstack
<VAR>obstack</VAR> using the fast growth functions.
<P>
While you know there is room, you can use these fast growth functions
for adding data to a growing object:
<P>
<A NAME="IDX194"></A>
<U>Function:</U> void <B>obstack_1grow_fast</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, char <VAR>c</VAR>)</I><P>
The function <CODE>obstack_1grow_fast</CODE> adds one byte containing the
character <VAR>c</VAR> to the growing object in obstack <VAR>obstack_ptr</VAR>.
<P>
<A NAME="IDX195"></A>
<U>Function:</U> void <B>obstack_blank_fast</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>, size_t <VAR>size</VAR>)</I><P>
The function <CODE>obstack_blank_fast</CODE> adds <VAR>size</VAR> bytes to the
growing object in obstack <VAR>obstack_ptr</VAR> without initializing them.
<P>
When you check for space using <CODE>obstack_room</CODE> and there is not
enough room for what you want to add, the fast growth functions
are not safe. In this case, simply use the corresponding ordinary
growth function instead. Very soon this will copy the object to a
new chunk; then there will be lots of room available again.
<P>
So, each time you use an ordinary growth function, check afterward for
sufficient space using <CODE>obstack_room</CODE>. Once the object is copied
to a new chunk, there will be plenty of space again, so the program will
start using the fast growth functions again.
<P>
Here is an example:
<P>
<PRE>
void
add_string (struct obstack *obstack, char *ptr, size_t len)
{
while (len > 0)
{
if (obstack_room (obstack) > len)
{
/* We have enough room: add everything fast. */
while (len-- > 0)
obstack_1grow_fast (obstack, *ptr++);
}
else
{
/* Not enough room. Add one character slowly,
which may copy to a new chunk and make room. */
obstack_1grow (obstack, *ptr++);
len--;
}
}
}
</PRE>
<P>
<A NAME="IDX196"></A>
<A NAME="IDX197"></A>
<H3><A NAME="SEC41" HREF="library_toc.html#SEC41" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC41">Status of an Obstack</A></H3>
<P>
Here are functions that provide information on the current status of
allocation in an obstack. You can use them to learn about an object while
still growing it.
<P>
<A NAME="IDX198"></A>
<U>Function:</U> void * <B>obstack_base</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
This function returns the tentative address of the beginning of the
currently growing object in <VAR>obstack_ptr</VAR>. If you finish the object
immediately, it will have that address. If you make it larger first, it
may outgrow the current chunk--then its address will change!
<P>
If no object is growing, this value says where the next object you
allocate will start (once again assuming it fits in the current
chunk).
<P>
<A NAME="IDX199"></A>
<U>Function:</U> void * <B>obstack_next_free</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
This function returns the address of the first free byte in the current
chunk of obstack <VAR>obstack_ptr</VAR>. This is the end of the currently
growing object. If no object is growing, <CODE>obstack_next_free</CODE>
returns the same value as <CODE>obstack_base</CODE>.
<P>
<A NAME="IDX200"></A>
<U>Function:</U> size_t <B>obstack_object_size</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>
This function returns the size in bytes of the currently growing object.
This is equivalent to
<P>
<PRE>
obstack_next_free (<VAR>obstack_ptr</VAR>) - obstack_base (<VAR>obstack_ptr</VAR>)
</PRE>
<P>
<A NAME="IDX201"></A>
<H3><A NAME="SEC42" HREF="library_toc.html#SEC42" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC42">Alignment of Data in Obstacks</A></H3>
<P>
Each obstack has an <DFN>alignment boundary</DFN>; each object allocated in
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -