⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 library_3.html

📁 Linux程序员的工作手册
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P>Note that a change in alignment mask does not take effect until<EM>after</EM> the next time an object is allocated or finished in theobstack.  If you are not growing an object, you can make the newalignment mask take effect immediately by calling <CODE>obstack_finish</CODE>.This will finish a zero-length object and then do proper alignment forthe next object.<P><A NAME="IDX203"></A><A NAME="IDX204"></A><H3><A NAME="SEC43" HREF="library_toc.html#SEC43" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC43">Obstack Chunks</A></H3><P>Obstacks work by allocating space for themselves in large chunks, andthen parceling out space in the chunks to satisfy your requests.  Chunksare normally 4096 bytes long unless you specify a different chunk size.The chunk size includes 8 bytes of overhead that are not actually usedfor storing objects.  Regardless of the specified size, longer chunkswill be allocated when necessary for long objects.<P>The obstack library allocates chunks by calling the function<CODE>obstack_chunk_alloc</CODE>, which you must define.  When a chunk is nolonger needed because you have freed all the objects in it, the obstacklibrary frees the chunk by calling <CODE>obstack_chunk_free</CODE>, which youmust also define.<P>These two must be defined (as macros) or declared (as functions) in eachsource file that uses <CODE>obstack_init</CODE> (see section <A HREF="library_3.html#SEC34" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC34">Creating Obstacks</A>).Most often they are defined as macros like this:<P><PRE>#define obstack_chunk_alloc xmalloc#define obstack_chunk_free free</PRE><P>Note that these are simple macros (no arguments).  Macro definitions witharguments will not work!  It is necessary that <CODE>obstack_chunk_alloc</CODE>or <CODE>obstack_chunk_free</CODE>, alone, expand into a function name if it isnot itself a function name.<P>The function that actually implements <CODE>obstack_chunk_alloc</CODE> cannotreturn "failure" in any fashion, because the obstack library is notprepared to handle failure.  Therefore, <CODE>malloc</CODE> itself is notsuitable.  If the function cannot obtain space, it should eitherterminate the process (see section <A HREF="library_22.html#SEC395" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_22.html#SEC395">Program Termination</A>) or do a nonlocalexit using <CODE>longjmp</CODE> (see section <A HREF="library_20.html#SEC326" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_20.html#SEC326">Non-Local Exits</A>).<P>If you allocate chunks with <CODE>malloc</CODE>, the chunk size should be apower of 2.  The default chunk size, 4096, was chosen because it is longenough to satisfy many typical requests on the obstack yet short enoughnot to waste too much memory in the portion of the last chunk not yet used.<P><A NAME="IDX205"></A><U>Macro:</U> size_t <B>obstack_chunk_size</B> <I>(struct obstack *<VAR>obstack_ptr</VAR>)</I><P>This returns the chunk size of the given obstack.<P>Since this macro expands to an lvalue, you can specify a new chunk size byassigning it a new value.  Doing so does not affect the chunks alreadyallocated, but will change the size of chunks allocated for that particularobstack in the future.  It is unlikely to be useful to make the chunk sizesmaller, but making it larger might improve efficiency if you areallocating many objects whose size is comparable to the chunk size.  Hereis how to do so cleanly:<P><PRE>if (obstack_chunk_size (obstack_ptr) &#60; <VAR>new_chunk_size</VAR>)  obstack_chunk_size (obstack_ptr) = <VAR>new_chunk_size</VAR>;</PRE><P><H3><A NAME="SEC44" HREF="library_toc.html#SEC44" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC44">Summary of Obstack Functions</A></H3><P>Here is a summary of all the functions associated with obstacks.  Eachtakes the address of an obstack (<CODE>struct obstack *</CODE>) as its firstargument.<P><DL COMPACT><DT><CODE>void obstack_init (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Initialize use of an obstack.  See section <A HREF="library_3.html#SEC34" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC34">Creating Obstacks</A>.<P><DT><CODE>void *obstack_alloc (struct obstack *<VAR>obstack_ptr</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Allocate an object of <VAR>size</VAR> uninitialized bytes.See section <A HREF="library_3.html#SEC36" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC36">Allocation in an Obstack</A>.<P><DT><CODE>void *obstack_copy (struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>address</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Allocate an object of <VAR>size</VAR> bytes, with contents copied from<VAR>address</VAR>.  See section <A HREF="library_3.html#SEC36" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC36">Allocation in an Obstack</A>.<P><DT><CODE>void *obstack_copy0 (struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>address</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Allocate an object of <VAR>size</VAR>+1 bytes, with <VAR>size</VAR> of them copiedfrom <VAR>address</VAR>, followed by a null character at the end.See section <A HREF="library_3.html#SEC36" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC36">Allocation in an Obstack</A>.<P><DT><CODE>void obstack_free (struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>object</VAR>)</CODE><DD>Free <VAR>object</VAR> (and everything allocated in the specified obstackmore recently than <VAR>object</VAR>).  See section <A HREF="library_3.html#SEC37" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC37">Freeing Objects in an Obstack</A>.<P><DT><CODE>void obstack_blank (struct obstack *<VAR>obstack_ptr</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Add <VAR>size</VAR> uninitialized bytes to a growing object.See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>void obstack_grow (struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>address</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Add <VAR>size</VAR> bytes, copied from <VAR>address</VAR>, to a growing object.See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>void obstack_grow0 (struct obstack *<VAR>obstack_ptr</VAR>, void *<VAR>address</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Add <VAR>size</VAR> bytes, copied from <VAR>address</VAR>, to a growing object,and then add another byte containing a null character.  See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>void obstack_1grow (struct obstack *<VAR>obstack_ptr</VAR>, char <VAR>data_char</VAR>)</CODE><DD>Add one byte containing <VAR>data_char</VAR> to a growing object.See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>void *obstack_finish (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Finalize the object that is growing and return its permanent address.See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>size_t obstack_object_size (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Get the current size of the currently growing object.  See section <A HREF="library_3.html#SEC39" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC39">Growing Objects</A>.<P><DT><CODE>void obstack_blank_fast (struct obstack *<VAR>obstack_ptr</VAR>, size_t <VAR>size</VAR>)</CODE><DD>Add <VAR>size</VAR> uninitialized bytes to a growing object without checkingthat there is enough room.  See section <A HREF="library_3.html#SEC40" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC40">Extra Fast Growing Objects</A>.<P><DT><CODE>void obstack_1grow_fast (struct obstack *<VAR>obstack_ptr</VAR>, char <VAR>data_char</VAR>)</CODE><DD>Add one byte containing <VAR>data_char</VAR> to a growing object withoutchecking that there is enough room.  See section <A HREF="library_3.html#SEC40" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC40">Extra Fast Growing Objects</A>.<P><DT><CODE>size_t obstack_room (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Get the amount of room now available for growing the current object.See section <A HREF="library_3.html#SEC40" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC40">Extra Fast Growing Objects</A>.<P><DT><CODE>int obstack_alignment_mask (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>The mask used for aligning the beginning of an object.  This is anlvalue.  See section <A HREF="library_3.html#SEC42" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC42">Alignment of Data in Obstacks</A>.<P><DT><CODE>size_t obstack_chunk_size (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>The size for allocating chunks.  This is an lvalue.  See section <A HREF="library_3.html#SEC43" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC43">Obstack Chunks</A>.<P><DT><CODE>void *obstack_base (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Tentative starting address of the currently growing object.See section <A HREF="library_3.html#SEC41" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC41">Status of an Obstack</A>.<P><DT><CODE>void *obstack_next_free (struct obstack *<VAR>obstack_ptr</VAR>)</CODE><DD>Address just after the end of the currently growing object.See section <A HREF="library_3.html#SEC41" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC41">Status of an Obstack</A>.</DL><P><A NAME="IDX206"></A><A NAME="IDX207"></A><A NAME="IDX208"></A><H2><A NAME="SEC45" HREF="library_toc.html#SEC45" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC45">Automatic Storage with Variable Size</A></H2><P>The function <CODE>alloca</CODE> supports a kind of half-dynamic allocation inwhich blocks are allocated dynamically but freed automatically.<P>Allocating a block with <CODE>alloca</CODE> is an explicit action; you canallocate as many blocks as you wish, and compute the size at run time.  Butall the blocks are freed when you exit the function that <CODE>alloca</CODE> wascalled from, just as if they were automatic variables declared in thatfunction.  There is no way to free the space explicitly.<P>The prototype for <CODE>alloca</CODE> is in <TT>`stdlib.h'</TT>.  This function isa BSD extension.<A NAME="IDX209"></A><P><A NAME="IDX210"></A><U>Function:</U> void * <B>alloca</B> <I>(size_t <VAR>size</VAR>);</I><P>The return value of <CODE>alloca</CODE> is the address of a block of <VAR>size</VAR>bytes of storage, allocated in the stack frame of the calling function.<P>Do not use <CODE>alloca</CODE> inside the arguments of a function call--youwill get unpredictable results, because the stack space for the<CODE>alloca</CODE> would appear on the stack in the middle of the space forthe function arguments.  An example of what to avoid is <CODE>foo (x,alloca (4), y)</CODE>.<P><H3><A NAME="SEC46" HREF="library_toc.html#SEC46" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC46"><CODE>alloca</CODE> Example</A></H3><P>As an example of use of <CODE>alloca</CODE>, here is a function that opens a filename made from concatenating two argument strings, and returns a filedescriptor or minus one signifying failure:<P><PRE>intopen2 (char *str1, char *str2, int flags, int mode){  char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);  strcpy (name, str1);  strcat (name, str2);  return open (name, flags, mode);}</PRE><P>Here is how you would get the same results with <CODE>malloc</CODE> and<CODE>free</CODE>:<P><PRE>intopen2 (char *str1, char *str2, int flags, int mode){  char *name = (char *) malloc (strlen (str1) + strlen (str2) + 1);  int desc;  if (name == 0)    fatal ("virtual memory exceeded");  strcpy (name, str1);  strcat (name, str2);  desc = open (name, flags, mode);  free (name);  return desc;}</PRE><P>As you can see, it is simpler with <CODE>alloca</CODE>.  But <CODE>alloca</CODE> hasother, more important advantages, and some disadvantages.<P><H3><A NAME="SEC47" HREF="library_toc.html#SEC47" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC47">Advantages of <CODE>alloca</CODE></A></H3><P>Here are the reasons why <CODE>alloca</CODE> may be preferable to <CODE>malloc</CODE>:<P><UL><LI>Using <CODE>alloca</CODE> wastes very little space and is very fast.  (It isopen-coded by the GNU C compiler.)<P><LI>Since <CODE>alloca</CODE> does not have separate pools for different sizes ofblock, space used for any size block can be reused for any other size.<CODE>alloca</CODE> does not cause storage fragmentation.<P><A NAME="IDX211"></A><LI>Nonlocal exits done with <CODE>longjmp</CODE> (see section <A HREF="library_20.html#SEC326" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_20.html#SEC326">Non-Local Exits</A>)automatically free the space allocated with <CODE>alloca</CODE> when they exitthrough the function that called <CODE>alloca</CODE>.  This is the mostimportant reason to use <CODE>alloca</CODE>.<P>To illustrate this, suppose you have a function<CODE>open_or_report_error</CODE> which returns a descriptor, like<CODE>open</CODE>, if it succeeds, but does not return to its caller if itfails.  If the file cannot be opened, it prints an error message andjumps out to the command level of your program using <CODE>longjmp</CODE>.Let's change <CODE>open2</CODE> (see section <A HREF="library_3.html#SEC46" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html#SEC46"><CODE>alloca</CODE> Example</A>) to use thissubroutine:<P><PRE>intopen2 (char *str1, char *str2, int flags, int mode){  char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);  strcpy (name, str1);  strcat (name, str2);  return open_or_report_error (name, flags, mode);}</PRE><P>Because of the way <CODE>alloca</CODE> works, the storage it allocates isfreed even when an error occurs, with no special effort required.<P>By contrast, the previous definition of <CODE>open2</CODE> (which uses<CODE>malloc</CODE> and <CODE>free</CODE>) would develop a storage leak if it werechanged in this way.  Even if you are willing to make more changes tofix it, there is no easy wa

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -