| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917 |
- @node Memory, Character Handling, Error Reporting, Top
- @chapter Virtual Memory Allocation And Paging
- @c %MENU% Allocating virtual memory and controlling paging
- @cindex memory allocation
- @cindex storage allocation
- This chapter describes how processes manage and use memory in a system
- that uses @theglibc{}.
- @Theglibc{} has several functions for dynamically allocating
- virtual memory in various ways. They vary in generality and in
- efficiency. The library also provides functions for controlling paging
- and allocation of real memory.
- @menu
- * Memory Concepts:: An introduction to concepts and terminology.
- * Memory Allocation:: Allocating storage for your program data
- * Resizing the Data Segment:: @code{brk}, @code{sbrk}
- * Memory Protection:: Controlling access to memory regions.
- * Locking Pages:: Preventing page faults
- @end menu
- Memory mapped I/O is not discussed in this chapter. @xref{Memory-mapped I/O}.
- @node Memory Concepts
- @section Process Memory Concepts
- One of the most basic resources a process has available to it is memory.
- There are a lot of different ways systems organize memory, but in a
- typical one, each process has one linear virtual address space, with
- addresses running from zero to some huge maximum. It need not be
- contiguous; i.e., not all of these addresses actually can be used to
- store data.
- The virtual memory is divided into pages (4 kilobytes is typical).
- Backing each page of virtual memory is a page of real memory (called a
- @dfn{frame}) or some secondary storage, usually disk space. The disk
- space might be swap space or just some ordinary disk file. Actually, a
- page of all zeroes sometimes has nothing at all backing it -- there's
- just a flag saying it is all zeroes.
- @cindex page frame
- @cindex frame, real memory
- @cindex swap space
- @cindex page, virtual memory
- The same frame of real memory or backing store can back multiple virtual
- pages belonging to multiple processes. This is normally the case, for
- example, with virtual memory occupied by @glibcadj{} code. The same
- real memory frame containing the @code{printf} function backs a virtual
- memory page in each of the existing processes that has a @code{printf}
- call in its program.
- In order for a program to access any part of a virtual page, the page
- must at that moment be backed by (``connected to'') a real frame. But
- because there is usually a lot more virtual memory than real memory, the
- pages must move back and forth between real memory and backing store
- regularly, coming into real memory when a process needs to access them
- and then retreating to backing store when not needed anymore. This
- movement is called @dfn{paging}.
- When a program attempts to access a page which is not at that moment
- backed by real memory, this is known as a @dfn{page fault}. When a page
- fault occurs, the kernel suspends the process, places the page into a
- real page frame (this is called ``paging in'' or ``faulting in''), then
- resumes the process so that from the process' point of view, the page
- was in real memory all along. In fact, to the process, all pages always
- seem to be in real memory. Except for one thing: the elapsed execution
- time of an instruction that would normally be a few nanoseconds is
- suddenly much, much, longer (because the kernel normally has to do I/O
- to complete the page-in). For programs sensitive to that, the functions
- described in @ref{Locking Pages} can control it.
- @cindex page fault
- @cindex paging
- Within each virtual address space, a process has to keep track of what
- is at which addresses, and that process is called memory allocation.
- Allocation usually brings to mind meting out scarce resources, but in
- the case of virtual memory, that's not a major goal, because there is
- generally much more of it than anyone needs. Memory allocation within a
- process is mainly just a matter of making sure that the same byte of
- memory isn't used to store two different things.
- Processes allocate memory in two major ways: by exec and
- programmatically. Actually, forking is a third way, but it's not very
- interesting. @xref{Creating a Process}.
- Exec is the operation of creating a virtual address space for a process,
- loading its basic program into it, and executing the program. It is
- done by the ``exec'' family of functions (e.g. @code{execl}). The
- operation takes a program file (an executable), it allocates space to
- load all the data in the executable, loads it, and transfers control to
- it. That data is most notably the instructions of the program (the
- @dfn{text}), but also literals and constants in the program and even
- some variables: C variables with the static storage class (@pxref{Memory
- Allocation and C}).
- @cindex executable
- @cindex literals
- @cindex constants
- Once that program begins to execute, it uses programmatic allocation to
- gain additional memory. In a C program with @theglibc{}, there
- are two kinds of programmatic allocation: automatic and dynamic.
- @xref{Memory Allocation and C}.
- Memory-mapped I/O is another form of dynamic virtual memory allocation.
- Mapping memory to a file means declaring that the contents of certain
- range of a process' addresses shall be identical to the contents of a
- specified regular file. The system makes the virtual memory initially
- contain the contents of the file, and if you modify the memory, the
- system writes the same modification to the file. Note that due to the
- magic of virtual memory and page faults, there is no reason for the
- system to do I/O to read the file, or allocate real memory for its
- contents, until the program accesses the virtual memory.
- @xref{Memory-mapped I/O}.
- @cindex memory mapped I/O
- @cindex memory mapped file
- @cindex files, accessing
- Just as it programmatically allocates memory, the program can
- programmatically deallocate (@dfn{free}) it. You can't free the memory
- that was allocated by exec. When the program exits or execs, you might
- say that all its memory gets freed, but since in both cases the address
- space ceases to exist, the point is really moot. @xref{Program
- Termination}.
- @cindex execing a program
- @cindex freeing memory
- @cindex exiting a program
- A process' virtual address space is divided into segments. A segment is
- a contiguous range of virtual addresses. Three important segments are:
- @itemize @bullet
- @item
- The @dfn{text segment} contains a program's instructions and literals and
- static constants. It is allocated by exec and stays the same size for
- the life of the virtual address space.
- @item
- The @dfn{data segment} is working storage for the program. It can be
- preallocated and preloaded by exec and the process can extend or shrink
- it by calling functions as described in @xref{Resizing the Data
- Segment}. Its lower end is fixed.
- @item
- The @dfn{stack segment} contains a program stack. It grows as the stack
- grows, but doesn't shrink when the stack shrinks.
- @end itemize
- @node Memory Allocation
- @section Allocating Storage For Program Data
- This section covers how ordinary programs manage storage for their data,
- including the famous @code{malloc} function and some fancier facilities
- special to @theglibc{} and GNU Compiler.
- @menu
- * Memory Allocation and C:: How to get different kinds of allocation in C.
- * The GNU Allocator:: An overview of the GNU @code{malloc}
- implementation.
- * Unconstrained Allocation:: The @code{malloc} facility allows fully general
- dynamic allocation.
- * Allocation Debugging:: Finding memory leaks and not freed memory.
- * Replacing malloc:: Using your own @code{malloc}-style allocator.
- * 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.
- @end menu
- @node Memory Allocation and C
- @subsection Memory Allocation in C Programs
- 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 (part of the exec operation), and is never freed.
- @cindex static memory allocation
- @cindex static storage class
- @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.
- @cindex automatic memory allocation
- @cindex automatic storage class
- In GNU C, the size of the automatic storage can be an expression
- that varies. In other C implementations, it must be a constant.
- @end itemize
- A third important kind of memory allocation, @dfn{dynamic allocation},
- is not supported by C variables but is available via @glibcadj{}
- functions.
- @cindex dynamic memory allocation
- @subsubsection Dynamic Memory Allocation
- @cindex dynamic memory 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 amount of memory you need, or how long you
- continue to need it, depends on factors that are not known before the
- program runs.
- 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 memory 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.
- 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 get dynamically
- allocated memory is via a system call (which is generally via a @glibcadj{}
- function call), and 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 = malloc (sizeof *ptr);
- ptr->name = x;
- ptr->next = current_foobar;
- current_foobar = ptr;
- @}
- @end smallexample
- @node The GNU Allocator
- @subsection The GNU Allocator
- @cindex gnu allocator
- The @code{malloc} implementation in @theglibc{} is derived from ptmalloc
- (pthreads malloc), which in turn is derived from dlmalloc (Doug Lea malloc).
- This @code{malloc} may allocate memory
- in two different ways depending on their size
- and certain parameters that may be controlled by users. The most common way is
- to allocate portions of memory (called chunks) from a large contiguous area of
- memory and manage these areas to optimize their use and reduce wastage in the
- form of unusable chunks. Traditionally the system heap was set up to be the one
- large memory area but the @glibcadj{} @code{malloc} implementation maintains
- multiple such areas to optimize their use in multi-threaded applications. Each
- such area is internally referred to as an @dfn{arena}.
- As opposed to other versions, the @code{malloc} in @theglibc{} does not round
- up chunk sizes to powers of two, neither for large nor for small sizes.
- Neighboring chunks can be coalesced on a @code{free} no matter what their size
- is. This makes the implementation suitable for all kinds of allocation
- patterns without generally incurring high memory waste through fragmentation.
- The presence of multiple arenas allows multiple threads to allocate
- memory simultaneously in separate arenas, thus improving performance.
- The other way of memory allocation is for very large blocks, i.e. much larger
- than a page. These requests are allocated with @code{mmap} (anonymous or via
- @file{/dev/zero}; @pxref{Memory-mapped I/O})). This has the great advantage
- that these chunks are returned to the system immediately when they are freed.
- Therefore, it cannot happen that a large chunk becomes ``locked'' in between
- smaller ones and even after calling @code{free} wastes memory. The size
- threshold for @code{mmap} to be used is dynamic and gets adjusted according to
- allocation patterns of the program. @code{mallopt} can be used to statically
- adjust the threshold using @code{M_MMAP_THRESHOLD} and the use of @code{mmap}
- can be disabled completely with @code{M_MMAP_MAX};
- @pxref{Malloc Tunable Parameters}.
- A more detailed technical description of the GNU Allocator is maintained in
- the @glibcadj{} wiki. See
- @uref{https://sourceware.org/glibc/wiki/MallocInternals}.
- It is possible to use your own custom @code{malloc} instead of the
- built-in allocator provided by @theglibc{}. @xref{Replacing malloc}.
- @node Unconstrained Allocation
- @subsection Unconstrained Allocation
- @cindex unconstrained memory 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.
- * Aligned Memory Blocks:: Allocating specially aligned memory.
- * Malloc Tunable Parameters:: Use @code{mallopt} to adjust allocation
- parameters.
- * Heap Consistency Checking:: Automatic checking for errors.
- * 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
- @subsubsection Basic Memory 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
- @deftypefun {void *} malloc (size_t @var{size})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Malloc hooks and __morecore pointers, as well as such parameters as
- @c max_n_mmaps and max_mmapped_mem, are accessed without guards, so they
- @c could pose a thread safety issue; in order to not declare malloc
- @c MT-unsafe, it's modifying the hooks and parameters while multiple
- @c threads are active that is regarded as unsafe. An arena's next field
- @c is initialized and never changed again, except for main_arena's,
- @c that's protected by list_lock; next_free is only modified while
- @c list_lock is held too. All other data members of an arena, as well
- @c as the metadata of the memory areas assigned to it, are only modified
- @c while holding the arena's mutex (fastbin pointers use atomic ops
- @c because they may be modified by free without taking the arena's
- @c lock). Some reassurance was needed for fastbins, for it wasn't clear
- @c how they were initialized. It turns out they are always
- @c zero-initialized: main_arena's, for being static data, and other
- @c arena's, for being just-mmapped memory.
- @c Leaking file descriptors and memory in case of cancellation is
- @c unavoidable without disabling cancellation, but the lock situation is
- @c a bit more complicated: we don't have fallback arenas for malloc to
- @c be safe to call from within signal handlers. Error-checking mutexes
- @c or trylock could enable us to try and use alternate arenas, even with
- @c -DPER_THREAD (enabled by default), but supporting interruption
- @c (cancellation or signal handling) while holding the arena list mutex
- @c would require more work; maybe blocking signals and disabling async
- @c cancellation while manipulating the arena lists?
- @c __libc_malloc @asulock @aculock @acsfd @acsmem
- @c force_reg ok
- @c *malloc_hook unguarded
- @c arena_lock @asulock @aculock @acsfd @acsmem
- @c mutex_lock @asulock @aculock
- @c arena_get2 @asulock @aculock @acsfd @acsmem
- @c get_free_list @asulock @aculock
- @c mutex_lock (list_lock) dup @asulock @aculock
- @c mutex_unlock (list_lock) dup @aculock
- @c mutex_lock (arena lock) dup @asulock @aculock [returns locked]
- @c __get_nprocs ext ok @acsfd
- @c NARENAS_FROM_NCORES ok
- @c atomic_compare_and_exchange_bool_acq ok
- @c _int_new_arena ok @asulock @aculock @acsmem
- @c new_heap ok @acsmem
- @c mmap ok @acsmem
- @c munmap ok @acsmem
- @c mprotect ok
- @c chunk2mem ok
- @c set_head ok
- @c tsd_setspecific dup ok
- @c mutex_init ok
- @c mutex_lock (just-created mutex) ok, returns locked
- @c mutex_lock (list_lock) dup @asulock @aculock
- @c atomic_write_barrier ok
- @c mutex_unlock (list_lock) @aculock
- @c atomic_fetch_add ok
- @c reused_arena @asulock @aculock
- @c reads&writes next_to_use and iterates over arena next without guards
- @c those are harmless as long as we don't drop arenas from the
- @c NEXT list, and we never do; when a thread terminates,
- @c __malloc_arena_thread_freeres prepends the arena to the free_list
- @c NEXT_FREE list, but NEXT is never modified, so it's safe!
- @c mutex_trylock (arena lock) @asulock @aculock
- @c mutex_lock (arena lock) dup @asulock @aculock
- @c tsd_setspecific dup ok
- @c _int_malloc @acsfd @acsmem
- @c checked_request2size ok
- @c REQUEST_OUT_OF_RANGE ok
- @c request2size ok
- @c get_max_fast ok
- @c fastbin_index ok
- @c fastbin ok
- @c atomic_compare_and_exhange_val_acq ok
- @c malloc_printerr dup @mtsenv
- @c if we get to it, we're toast already, undefined behavior must have
- @c been invoked before
- @c libc_message @mtsenv [no leaks with cancellation disabled]
- @c FATAL_PREPARE ok
- @c pthread_setcancelstate disable ok
- @c libc_secure_getenv @mtsenv
- @c getenv @mtsenv
- @c open_not_cancel_2 dup @acsfd
- @c strchrnul ok
- @c WRITEV_FOR_FATAL ok
- @c writev ok
- @c mmap ok @acsmem
- @c munmap ok @acsmem
- @c BEFORE_ABORT @acsfd
- @c backtrace ok
- @c write_not_cancel dup ok
- @c backtrace_symbols_fd @aculock
- @c open_not_cancel_2 dup @acsfd
- @c read_not_cancel dup ok
- @c close_not_cancel_no_status dup @acsfd
- @c abort ok
- @c itoa_word ok
- @c abort ok
- @c check_remalloced_chunk ok/disabled
- @c chunk2mem dup ok
- @c alloc_perturb ok
- @c in_smallbin_range ok
- @c smallbin_index ok
- @c bin_at ok
- @c last ok
- @c malloc_consolidate ok
- @c get_max_fast dup ok
- @c clear_fastchunks ok
- @c unsorted_chunks dup ok
- @c fastbin dup ok
- @c atomic_exchange_acquire ok
- @c check_inuse_chunk dup ok/disabled
- @c chunk_at_offset dup ok
- @c chunksize dup ok
- @c inuse_bit_at_offset dup ok
- @c unlink dup ok
- @c clear_inuse_bit_at_offset dup ok
- @c in_smallbin_range dup ok
- @c set_head dup ok
- @c malloc_init_state ok
- @c bin_at dup ok
- @c set_noncontiguous dup ok
- @c set_max_fast dup ok
- @c initial_top ok
- @c unsorted_chunks dup ok
- @c check_malloc_state ok/disabled
- @c set_inuse_bit_at_offset ok
- @c check_malloced_chunk ok/disabled
- @c largebin_index ok
- @c have_fastchunks ok
- @c unsorted_chunks ok
- @c bin_at ok
- @c chunksize ok
- @c chunk_at_offset ok
- @c set_head ok
- @c set_foot ok
- @c mark_bin ok
- @c idx2bit ok
- @c first ok
- @c unlink ok
- @c malloc_printerr dup ok
- @c in_smallbin_range dup ok
- @c idx2block ok
- @c idx2bit dup ok
- @c next_bin ok
- @c sysmalloc @acsfd @acsmem
- @c MMAP @acsmem
- @c set_head dup ok
- @c check_chunk ok/disabled
- @c chunk2mem dup ok
- @c chunksize dup ok
- @c chunk_at_offset dup ok
- @c heap_for_ptr ok
- @c grow_heap ok
- @c mprotect ok
- @c set_head dup ok
- @c new_heap @acsmem
- @c MMAP dup @acsmem
- @c munmap @acsmem
- @c top ok
- @c set_foot dup ok
- @c contiguous ok
- @c MORECORE ok
- @c *__morecore ok unguarded
- @c __default_morecore
- @c sbrk ok
- @c force_reg dup ok
- @c *__after_morecore_hook unguarded
- @c set_noncontiguous ok
- @c malloc_printerr dup ok
- @c _int_free (have_lock) @acsfd @acsmem [@asulock @aculock]
- @c chunksize dup ok
- @c mutex_unlock dup @aculock/!have_lock
- @c malloc_printerr dup ok
- @c check_inuse_chunk ok/disabled
- @c chunk_at_offset dup ok
- @c mutex_lock dup @asulock @aculock/@have_lock
- @c chunk2mem dup ok
- @c free_perturb ok
- @c set_fastchunks ok
- @c fastbin_index dup ok
- @c fastbin dup ok
- @c atomic_compare_and_exchange_val_rel ok
- @c chunk_is_mmapped ok
- @c contiguous dup ok
- @c prev_inuse ok
- @c unlink dup ok
- @c inuse_bit_at_offset dup ok
- @c clear_inuse_bit_at_offset ok
- @c unsorted_chunks dup ok
- @c in_smallbin_range dup ok
- @c set_head dup ok
- @c set_foot dup ok
- @c check_free_chunk ok/disabled
- @c check_chunk dup ok/disabled
- @c have_fastchunks dup ok
- @c malloc_consolidate dup ok
- @c systrim ok
- @c MORECORE dup ok
- @c *__after_morecore_hook dup unguarded
- @c set_head dup ok
- @c check_malloc_state ok/disabled
- @c top dup ok
- @c heap_for_ptr dup ok
- @c heap_trim @acsfd @acsmem
- @c top dup ok
- @c chunk_at_offset dup ok
- @c prev_chunk ok
- @c chunksize dup ok
- @c prev_inuse dup ok
- @c delete_heap @acsmem
- @c munmap dup @acsmem
- @c unlink dup ok
- @c set_head dup ok
- @c shrink_heap @acsfd
- @c check_may_shrink_heap @acsfd
- @c open_not_cancel_2 @acsfd
- @c read_not_cancel ok
- @c close_not_cancel_no_status @acsfd
- @c MMAP dup ok
- @c madvise ok
- @c munmap_chunk @acsmem
- @c chunksize dup ok
- @c chunk_is_mmapped dup ok
- @c chunk2mem dup ok
- @c malloc_printerr dup ok
- @c munmap dup @acsmem
- @c check_malloc_state ok/disabled
- @c arena_get_retry @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- @c mutex_lock dup @asulock @aculock
- @c arena_get2 dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock @aculock
- @c mem2chunk ok
- @c chunk_is_mmapped ok
- @c arena_for_chunk ok
- @c chunk_non_main_arena ok
- @c heap_for_ptr ok
- This function returns a pointer to a newly allocated block @var{size}
- bytes long, or a null pointer (setting @code{errno})
- 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 convert the value to 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 Strings and Arrays}):
- @smallexample
- struct foo *ptr = malloc (sizeof *ptr);
- 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 @w{ISO C} automatically converts the type
- @code{void *} to another type of pointer when necessary. However, a cast
- is necessary if the type is needed but not specified by context.
- 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 = malloc (length + 1);
- @end smallexample
- @noindent
- @xref{Representation of Strings}, for more information about this.
- @node Malloc Examples
- @subsubsection 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:
- @cindex @code{xmalloc} function
- @smallexample
- void *
- xmalloc (size_t size)
- @{
- 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)
- @{
- char *value = xmalloc (len + 1);
- value[len] = '\0';
- return memcpy (value, ptr, len);
- @}
- @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. On @gnusystems{}, the address is
- always a multiple of eight on 32-bit systems, and a multiple of 16 on
- 64-bit systems. Only rarely is any higher boundary (such as a page
- boundary) necessary; for those cases, use @code{aligned_alloc} or
- @code{posix_memalign} (@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}).
- @strong{Portability Notes:}
- @itemize @bullet
- @item
- In @theglibc{}, a successful @code{malloc (0)}
- returns a non-null pointer to a newly allocated size-zero block;
- other implementations may return @code{NULL} instead.
- POSIX and the ISO C standard allow both behaviors.
- @item
- In @theglibc{}, a failed @code{malloc} call sets @code{errno},
- but ISO C does not require this and non-POSIX implementations
- need not set @code{errno} when failing.
- @item
- In @theglibc{}, @code{malloc} always fails when @var{size} exceeds
- @code{PTRDIFF_MAX}, to avoid problems with programs that subtract
- pointers or use signed indexes. Other implementations may succeed in
- this case, leading to undefined behavior later.
- @end itemize
- @node Freeing after Malloc
- @subsubsection 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
- @deftypefun void free (void *@var{ptr})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c __libc_free @asulock @aculock @acsfd @acsmem
- @c releasing memory into fastbins modifies the arena without taking
- @c its mutex, but atomic operations ensure safety. If two (or more)
- @c threads are running malloc and have their own arenas locked when
- @c each gets a signal whose handler free()s large (non-fastbin-able)
- @c blocks from each other's arena, we deadlock; this is a more general
- @c case of @asulock.
- @c *__free_hook unguarded
- @c mem2chunk ok
- @c chunk_is_mmapped ok, chunk bits not modified after allocation
- @c chunksize ok
- @c munmap_chunk dup @acsmem
- @c arena_for_chunk dup ok
- @c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
- The @code{free} function deallocates the block of memory pointed at
- by @var{ptr}.
- @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}.
- The @code{free} function preserves the value of @code{errno}, so that
- cleanup code need not worry about saving and restoring @code{errno}
- around a call to @code{free}. Although neither @w{ISO C} nor
- POSIX.1-2017 requires @code{free} to preserve @code{errno}, a future
- version of POSIX is planned to require it.
- 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.
- @deftypefun void free_sized (void *@var{ptr}, size_t @var{size})
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- The @code{free_sized} function deallocates the block of memory pointed at
- by @var{ptr} that was previously allocated by @code{malloc}, @code{calloc}
- or @code{realloc}. The size @var{size} must match the previously requested
- total size provided to @code{malloc}, @code{calloc} or @code{realloc}.
- Attempting to deallocated memory allocated by @code{aligned_alloc},
- @code{memalign}, @code{posix_memalign}, @code{valloc} or @code{pvalloc} is
- undefined behavior. For @code{aligned_alloc}, @code{memalign} or
- @code{posix_memalign} use @code{free_aligned_sized} instead. Additionally
- it is also undefined behavior to call @code{free_sized} for allocations
- which the caller did not directly allocate but must still deallocate, such
- as the result of @code{strdup} or @code{strndup}. Instead continue using
- @code{free} for these cases.
- @end deftypefun
- @deftypefun void free_aligned_sized (void *@var{ptr}, size_t @var{alignment}, size_t @var{size})
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- The @code{free_aligned_sized} function deallocates the block of memory
- pointed at by @var{ptr} that was previously allocated by
- @code{aligned_alloc}, @code{memalign} or @code{posix_memalign}.
- The size @var{size} and alignment @var{alignment} must match the
- previously requested size and alignment provided to
- @code{aligned_alloc}, @code{memalign} or @code{posix_memalign}.
- @end deftypefun
- @node Changing Block Size
- @subsubsection 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} or
- @code{reallocarray}. These functions are declared in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun {void *} realloc (void *@var{ptr}, size_t @var{newsize})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c It may call the implementations of malloc and free, so all of their
- @c issues arise, plus the realloc hook, also accessed without guards.
- @c __libc_realloc @asulock @aculock @acsfd @acsmem
- @c *__realloc_hook unguarded
- @c __libc_free dup @asulock @aculock @acsfd @acsmem
- @c __libc_malloc dup @asulock @aculock @acsfd @acsmem
- @c mem2chunk dup ok
- @c chunksize dup ok
- @c malloc_printerr dup ok
- @c checked_request2size dup ok
- @c chunk_is_mmapped dup ok
- @c mremap_chunk
- @c chunksize dup ok
- @c __mremap ok
- @c set_head dup ok
- @c MALLOC_COPY ok
- @c memcpy ok
- @c munmap_chunk dup @acsmem
- @c arena_for_chunk dup ok
- @c mutex_lock (arena mutex) dup @asulock @aculock
- @c _int_realloc @acsfd @acsmem
- @c malloc_printerr dup ok
- @c check_inuse_chunk dup ok/disabled
- @c chunk_at_offset dup ok
- @c chunksize dup ok
- @c set_head_size dup ok
- @c chunk_at_offset dup ok
- @c set_head dup ok
- @c chunk2mem dup ok
- @c inuse dup ok
- @c unlink dup ok
- @c _int_malloc dup @acsfd @acsmem
- @c mem2chunk dup ok
- @c MALLOC_COPY dup ok
- @c _int_free (have_lock) dup @acsfd @acsmem
- @c set_inuse_bit_at_offset dup ok
- @c set_head dup ok
- @c mutex_unlock (arena mutex) dup @aculock
- @c _int_free (!have_lock) dup @asulock @aculock @acsfd @acsmem
- 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})}.
- Otherwise, if @var{newsize} is zero
- @code{realloc} frees the block and returns @code{NULL}.
- Otherwise, if @code{realloc} cannot reallocate the requested size
- it returns @code{NULL} and sets @code{errno}; the original block
- is left undisturbed.
- @end deftypefun
- @deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
- @standards{POSIX.1-2024, malloc.h}
- @standards{POSIX.1-2024, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- The @code{reallocarray} function changes the size of the block whose address
- is @var{ptr} to be long enough to contain a vector of @var{nmemb} elements,
- each of size @var{size}. It is equivalent to @samp{realloc (@var{ptr},
- @var{nmemb} * @var{size})}, except that @code{reallocarray} fails safely if
- the multiplication overflows, by setting @code{errno} to @code{ENOMEM},
- returning a null pointer, and leaving the original block unchanged.
- @code{reallocarray} should be used instead of @code{realloc} when the new size
- of the allocated block is the result of a multiplication that might overflow.
- This function was originally derived from OpenBSD 5.6, but was added in
- POSIX.1-2024.
- @end deftypefun
- Like @code{malloc}, @code{realloc} and @code{reallocarray} 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 subroutines,
- conventionally called @code{xrealloc} and @code{xreallocarray},
- that take care of the error message
- as @code{xmalloc} does for @code{malloc}:
- @cindex @code{xrealloc} and @code{xreallocarray} functions
- @smallexample
- void *
- xreallocarray (void *ptr, size_t nmemb, size_t size)
- @{
- void *value = reallocarray (ptr, nmemb, size);
- if (value == 0)
- fatal ("Virtual memory exhausted");
- return value;
- @}
- void *
- xrealloc (void *ptr, size_t size)
- @{
- return xreallocarray (ptr, 1, size);
- @}
- @end smallexample
- You can also use @code{realloc} or @code{reallocarray} 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.
- @comment The following is no longer true with the new malloc.
- @comment But it seems wise to keep the warning for other implementations.
- In several allocation implementations, making a block smaller sometimes
- necessitates copying it, so it can fail if no other space is available.
- @strong{Portability Notes:}
- @itemize @bullet
- @item
- Portable programs should not attempt to reallocate blocks to be size zero.
- On other implementations if @var{ptr} is non-null, @code{realloc (ptr, 0)}
- might free the block and return a non-null pointer to a size-zero
- object, or it might fail and return @code{NULL} without freeing the block.
- The ISO C17 standard allows these variations.
- @item
- In @theglibc{}, reallocation fails if the resulting block
- would exceed @code{PTRDIFF_MAX} in size, to avoid problems with programs
- that subtract pointers or use signed indexes. Other implementations may
- succeed, leading to undefined behavior later.
- @item
- In @theglibc{}, if the new size is the same as the old, @code{realloc} and
- @code{reallocarray} are guaranteed to change nothing and return the same
- address that you gave. However, POSIX and ISO C allow the functions
- to relocate the object or fail in this situation.
- @end itemize
- @node Allocating Cleared Space
- @subsubsection Allocating Cleared Space
- The function @code{calloc} allocates memory and clears it to zero. It
- is declared in @file{stdlib.h}.
- @pindex stdlib.h
- @deftypefun {void *} calloc (size_t @var{count}, size_t @var{eltsize})
- @standards{ISO, malloc.h}
- @standards{ISO, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Same caveats as malloc.
- @c __libc_calloc @asulock @aculock @acsfd @acsmem
- @c *__malloc_hook dup unguarded
- @c memset dup ok
- @c arena_get @asulock @aculock @acsfd @acsmem
- @c arena_lock dup @asulock @aculock @acsfd @acsmem
- @c top dup ok
- @c chunksize dup ok
- @c heap_for_ptr dup ok
- @c _int_malloc dup @acsfd @acsmem
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- @c mem2chunk dup ok
- @c chunk_is_mmapped dup ok
- @c MALLOC_ZERO ok
- @c memset dup ok
- 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)
- @{
- void *value = reallocarray (0, count, eltsize);
- if (value != 0)
- memset (value, 0, count * eltsize);
- return value;
- @}
- @end smallexample
- But in general, it is not guaranteed that @code{calloc} calls
- @code{reallocarray} and @code{memset} internally. For example, if the
- @code{calloc} implementation knows for other reasons that the new
- memory block is zero, it need not zero out the block again with
- @code{memset}. Also, if an application provides its own
- @code{reallocarray} outside the C library, @code{calloc} might not use
- that redefinition. @xref{Replacing malloc}.
- @node Aligned Memory Blocks
- @subsubsection 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
- @gnusystems{} is always a multiple of eight (or sixteen on 64-bit
- systems). If you need a block whose address is a multiple of a higher
- power of two than that, use @code{aligned_alloc} or @code{posix_memalign}.
- @code{aligned_alloc} and @code{posix_memalign} are declared in
- @file{stdlib.h}.
- @deftypefun {void *} aligned_alloc (size_t @var{alignment}, size_t @var{size})
- @standards{???, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Alias to memalign.
- The @code{aligned_alloc} function allocates a block of @var{size} bytes whose
- address is a multiple of @var{alignment}. The @var{alignment} must be a
- power of two.
- The @code{aligned_alloc} function returns a null pointer on error and sets
- @code{errno} to one of the following values:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{alignment} is not a power of two.
- This function was introduced in @w{ISO C11} and hence may have better
- portability to modern non-POSIX systems than @code{posix_memalign}.
- @end table
- @end deftypefun
- @deftypefun {void *} memalign (size_t @var{boundary}, size_t @var{size})
- @standards{BSD, malloc.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Same issues as malloc. The padding bytes are safely freed in
- @c _int_memalign, with the arena still locked.
- @c __libc_memalign @asulock @aculock @acsfd @acsmem
- @c *__memalign_hook dup unguarded
- @c __libc_malloc dup @asulock @aculock @acsfd @acsmem
- @c arena_get dup @asulock @aculock @acsfd @acsmem
- @c _int_memalign @acsfd @acsmem
- @c _int_malloc dup @acsfd @acsmem
- @c checked_request2size dup ok
- @c mem2chunk dup ok
- @c chunksize dup ok
- @c chunk_is_mmapped dup ok
- @c set_head dup ok
- @c chunk2mem dup ok
- @c set_inuse_bit_at_offset dup ok
- @c set_head_size dup ok
- @c _int_free (have_lock) dup @acsfd @acsmem
- @c chunk_at_offset dup ok
- @c check_inuse_chunk dup ok
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c mutex_unlock dup @aculock
- 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 allocating a
- somewhat larger block, and then returning an address within the block
- that is on the specified boundary.
- The @code{memalign} function returns a null pointer on error and sets
- @code{errno} to one of the following values:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{boundary} is not a power of two.
- @end table
- The @code{memalign} function is obsolete and @code{aligned_alloc} or
- @code{posix_memalign} should be used instead.
- @end deftypefun
- @deftypefun int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
- @standards{POSIX, stdlib.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}}
- @c Calls memalign unless the requirements are not met (powerof2 macro is
- @c safe given an automatic variable as an argument) or there's a
- @c memalign hook (accessed unguarded, but safely).
- The @code{posix_memalign} function is similar to the @code{memalign}
- function in that it returns a buffer of @var{size} bytes aligned to a
- multiple of @var{alignment}. But it adds one requirement to the
- parameter @var{alignment}: the value must be a power of two multiple of
- @code{sizeof (void *)}.
- If the function succeeds in allocation memory a pointer to the allocated
- memory is returned in @code{*@var{memptr}} and the return value is zero.
- Otherwise the function returns an error value indicating the problem.
- The possible error values returned are:
- @table @code
- @item ENOMEM
- There was insufficient memory available to satisfy the request.
- @item EINVAL
- @var{alignment} is not a power of two multiple of @code{sizeof (void *)}.
- @end table
- This function was introduced in POSIX 1003.1d. Although this function is
- superseded by @code{aligned_alloc}, it is more portable to older POSIX
- systems that do not support @w{ISO C11}.
- @end deftypefun
- @deftypefun {void *} valloc (size_t @var{size})
- @standards{BSD, malloc.h}
- @standards{BSD, stdlib.h}
- @safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{} @acsfd{} @acsmem{}}}
- @c __libc_valloc @mtuinit @asuinit @asulock @aculock @acsfd @acsmem
- @c ptmalloc_init (once) @mtsenv @asulock @aculock @acsfd @acsmem
- @c _dl_addr @asucorrupt? @aculock
- @c __rtld_lock_lock_recursive (dl_load_lock) @asucorrupt? @aculock
- @c _dl_find_dso_for_object ok, iterates over dl_ns and its _ns_loaded objs
- @c the ok above assumes no partial updates on dl_ns and _ns_loaded
- @c that could confuse a _dl_addr call in a signal handler
- @c _dl_addr_inside_object ok
- @c determine_info ok
- @c __rtld_lock_unlock_recursive (dl_load_lock) @aculock
- @c *_environ @mtsenv
- @c next_env_entry ok
- @c strcspn dup ok
- @c __libc_mallopt dup @mtasuconst:mallopt [setting mp_]
- @c *__malloc_initialize_hook unguarded, ok
- @c *__memalign_hook dup ok, unguarded
- @c arena_get dup @asulock @aculock @acsfd @acsmem
- @c _int_valloc @acsfd @acsmem
- @c malloc_consolidate dup ok
- @c _int_memalign dup @acsfd @acsmem
- @c arena_get_retry dup @asulock @aculock @acsfd @acsmem
- @c _int_memalign dup @acsfd @acsmem
- @c mutex_unlock dup @aculock
- Using @code{valloc} is like using @code{memalign} and passing the page size
- as the value of the first argument. It is implemented like this:
- @smallexample
- void *
- valloc (size_t size)
- @{
- return memalign (getpagesize (), size);
- @}
- @end smallexample
- @ref{Query Memory Parameters} for more information about the memory
- subsystem.
- The @code{valloc} function is obsolete and @code{aligned_alloc} or
- @code{posix_memalign} should be used instead.
- @end deftypefun
- You can determine the alignment of a pointer with the
- @code{memalignment} function.
- @deftypefun size_t memalignment (void *@var{p})
- @standards{C23, stdlib.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This function, defined in C23, returns the alignment of @var{p}, as a
- power of two. If @var{p} is a null pointer, it returns zero. C23
- requires @var{p} to be a valid pointer to an object or a null pointer;
- as a GNU extension, @theglibc{} supports this function on arbitrary
- bit patterns of pointer type.
- This function was added to the C23 standard to support unconventional
- platforms where a pointer's low-order bits are unrelated to alignment.
- For conventional platforms, one can instead cast the pointer to
- @code{uintptr_t} and then test the low order bits:
- this is portable to pre-C23 and is typically a bit faster.
- For example, if you want to read an @code{int}
- addressed by possibly-misaligned pointer @code{p},
- the following pre-C23 code works on all conventional platforms:
- @smallexample
- int i;
- if (((uintptr_t) p & (alignof (int) - 1)) != 0)
- memcpy (&i, p, sizeof i);
- else
- i = *p;
- @end smallexample
- However, it might not work on unconventional platforms, where one
- would need something like the following C23 code:
- @smallexample
- int i;
- if (memalignment (p) < alignof (int))
- memcpy (&i, p, sizeof i);
- else
- i = *p;
- @end smallexample
- However, for this particular case, performance does not improve if
- different code is used for aligned and unaligned pointers,
- and the following code is preferable:
- @smallexample
- int i;
- memcpy (&i, p, sizeof i);
- @end smallexample
- The compiler will generate the most efficient way to access unaligned
- data for the architecture, optimizing away the @code{memcpy} call.
- @end deftypefun
- @node Malloc Tunable Parameters
- @subsubsection Malloc Tunable Parameters
- You can adjust some parameters for dynamic memory allocation with the
- @code{mallopt} function. This function is the general SVID/XPG
- interface, defined in @file{malloc.h}.
- @pindex malloc.h
- @deftypefun int mallopt (int @var{param}, int @var{value})
- @safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
- @c __libc_mallopt @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
- @c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
- @c mutex_lock (main_arena->mutex) @asulock @aculock
- @c malloc_consolidate dup ok
- @c set_max_fast ok
- @c mutex_unlock dup @aculock
- When calling @code{mallopt}, the @var{param} argument specifies the
- parameter to be set, and @var{value} the new value to be set. Possible
- choices for @var{param}, as defined in @file{malloc.h}, are:
- @vtable @code
- @item M_MMAP_MAX
- The maximum number of chunks to allocate with @code{mmap}. Setting this
- to zero disables all use of @code{mmap}.
- The default value of this parameter is @code{65536}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_MMAP_MAX_} to the desired value.
- @item M_MMAP_THRESHOLD
- All chunks larger than this value are allocated outside the normal
- heap, using the @code{mmap} system call. This way it is guaranteed
- that the memory for these chunks can be returned to the system on
- @code{free}. Note that requests smaller than this threshold might still
- be allocated via @code{mmap}.
- If this parameter is not set, the default value is set as 128 KiB and the
- threshold is adjusted dynamically to suit the allocation patterns of the
- program. If the parameter is set, the dynamic adjustment is disabled and the
- value is set statically to the input value.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_MMAP_THRESHOLD_} to the desired value.
- @comment TODO: @item M_MXFAST
- @item M_PERTURB
- If non-zero, memory blocks are filled with values depending on some
- low order bits of this parameter when they are allocated (except when
- allocated by @code{calloc}) and freed. This can be used to debug the
- use of uninitialized or freed heap memory. Note that this option does not
- guarantee that the freed block will have any specific values. It only
- guarantees that the content the block had before it was freed will be
- overwritten.
- The default value of this parameter is @code{0}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_PERTURB_} to the desired value.
- @item M_TOP_PAD
- This parameter determines the amount of extra memory to obtain from the system
- when an arena needs to be extended. It also specifies the number of bytes to
- retain when shrinking an arena. This provides the necessary hysteresis in heap
- size such that excessive amounts of system calls can be avoided.
- The default value of this parameter is @code{0}.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_TOP_PAD_} to the desired value.
- @item M_TRIM_THRESHOLD
- This is the minimum size (in bytes) of the top-most, releasable chunk
- that will trigger a system call in order to return memory to the system.
- If this parameter is not set, the default value is set as 128 KiB and the
- threshold is adjusted dynamically to suit the allocation patterns of the
- program. If the parameter is set, the dynamic adjustment is disabled and the
- value is set statically to the provided input.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_TRIM_THRESHOLD_} to the desired value.
- @item M_ARENA_TEST
- This parameter specifies the number of arenas that can be created before the
- test on the limit to the number of arenas is conducted. The value is ignored if
- @code{M_ARENA_MAX} is set.
- The default value of this parameter is 2 on 32-bit systems and 8 on 64-bit
- systems.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_ARENA_TEST} to the desired value.
- @item M_ARENA_MAX
- This parameter sets the number of arenas to use regardless of the number of
- cores in the system.
- The default value of this tunable is @code{0}, meaning that the limit on the
- number of arenas is determined by the number of CPU cores online. For 32-bit
- systems the limit is twice the number of cores online and on 64-bit systems, it
- is eight times the number of cores online. Note that the default value is not
- derived from the default value of M_ARENA_TEST and is computed independently.
- This parameter can also be set for the process at startup by setting the
- environment variable @env{MALLOC_ARENA_MAX} to the desired value.
- @end vtable
- @end deftypefun
- @node Heap Consistency Checking
- @subsubsection Heap Consistency Checking
- @cindex heap consistency checking
- @cindex consistency checking, of heap
- You can ask @code{malloc} to check the consistency of dynamic memory by
- using the @code{mcheck} function and preloading the malloc debug library
- @file{libc_malloc_debug} using the @var{LD_PRELOAD} environment variable.
- This function is a GNU extension, declared in @file{mcheck.h}.
- @pindex mcheck.h
- @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status}))
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
- @c The hooks must be set up before malloc is first used, which sort of
- @c implies @mtuinit/@asuinit but since the function is a no-op if malloc
- @c was already used, that doesn't pose any safety issues. The actual
- @c problem is with the hooks, designed for single-threaded
- @c fully-synchronous operation: they manage an unguarded linked list of
- @c allocated blocks, and get temporarily overwritten before calling the
- @c allocation functions recursively while holding the old hooks. There
- @c are no guards for thread safety, and inconsistent hooks may be found
- @c within signal handlers or left behind in case of cancellation.
- 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. Alternatively you might use
- a debugger to insert a call to @code{mcheck} whenever the program is
- started, for example these gdb commands will automatically call @code{mcheck}
- whenever the program starts:
- @smallexample
- (gdb) break main
- Breakpoint 1, main (argc=2, argv=0xbffff964) at whatever.c:10
- (gdb) command 1
- Type commands for when breakpoint 1 is hit, one per line.
- End with a line saying just "end".
- >call mcheck(0)
- >continue
- >end
- (gdb) @dots{}
- @end smallexample
- This will however only work if no initialization function of any object
- involved calls any of the @code{malloc} functions since @code{mcheck}
- must be called before the first such function.
- @end deftypefun
- @deftypefun {enum mcheck_status} mprobe (void *@var{pointer})
- @safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
- @c The linked list of headers may be modified concurrently by other
- @c threads, and it may find a partial update if called from a signal
- @c handler. It's mostly read only, so cancelling it might be safe, but
- @c it will modify global state that, if cancellation hits at just the
- @c right spot, may be left behind inconsistent. This path is only taken
- @c if checkhdr finds an inconsistency. If the inconsistency could only
- @c occur because of earlier undefined behavior, that wouldn't be an
- @c additional safety issue problem, but because of the other concurrency
- @c issues in the mcheck hooks, the apparent inconsistency could be the
- @c result of mcheck's own internal data race. So, AC-Unsafe it is.
- 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
- Another possibility to check for and guard against bugs in the use of
- @code{malloc}, @code{realloc} and @code{free} is to set the environment
- variable @code{MALLOC_CHECK_}. When @code{MALLOC_CHECK_} is set to a
- non-zero value less than 4, a special (less efficient) implementation is
- used which is designed to be tolerant against simple errors, such as
- double calls of @code{free} with the same argument, or overruns of a
- single byte (off-by-one bugs). Not all such errors can be protected
- against, however, and memory leaks can result. Like in the case of
- @code{mcheck}, one would need to preload the @file{libc_malloc_debug}
- library to enable @code{MALLOC_CHECK_} functionality. Without this
- preloaded library, setting @code{MALLOC_CHECK_} will have no effect.
- Any detected heap corruption results in immediate termination of the
- process.
- There is one problem with @code{MALLOC_CHECK_}: in SUID or SGID binaries
- it could possibly be exploited since diverging from the normal programs
- behavior it now writes something to the standard error descriptor.
- Therefore the use of @code{MALLOC_CHECK_} is disabled by default for
- SUID and SGID binaries.
- So, what's the difference between using @code{MALLOC_CHECK_} and linking
- with @samp{-lmcheck}? @code{MALLOC_CHECK_} is orthogonal with respect to
- @samp{-lmcheck}. @samp{-lmcheck} has been added for backward
- compatibility. Both @code{MALLOC_CHECK_} and @samp{-lmcheck} should
- uncover the same bugs - but using @code{MALLOC_CHECK_} you don't need to
- recompile your application.
- @c __morecore, __after_morecore_hook are undocumented
- @c It's not clear whether to document them.
- @node Statistics of Malloc
- @subsubsection Statistics for Memory Allocation with @code{malloc}
- @cindex allocation statistics
- You can get information about dynamic memory allocation by calling the
- @code{mallinfo2} function. This function and its associated data type
- are declared in @file{malloc.h}; they are an extension of the standard
- SVID/XPG version.
- @pindex malloc.h
- @deftp {Data Type} {struct mallinfo2}
- @standards{GNU, malloc.h}
- This structure type is used to return information about the dynamic
- memory allocator. It contains the following members:
- @table @code
- @item size_t arena
- This is the total size of memory allocated with @code{sbrk} by
- @code{malloc}, in bytes.
- @item size_t ordblks
- This is the number of chunks not in use. (The memory allocator
- internally gets chunks of memory from the operating system, and then
- carves them up to satisfy individual @code{malloc} requests;
- @pxref{The GNU Allocator}.)
- @item size_t smblks
- This field is unused.
- @item size_t hblks
- This is the total number of chunks allocated with @code{mmap}.
- @item size_t hblkhd
- This is the total size of memory allocated with @code{mmap}, in bytes.
- @item size_t usmblks
- This field is unused and always 0.
- @item size_t fsmblks
- This field is unused.
- @item size_t uordblks
- This is the total size of memory occupied by chunks handed out by
- @code{malloc}.
- @item size_t fordblks
- This is the total size of memory occupied by free (not in use) chunks.
- @item size_t keepcost
- This is the size of the top-most releasable chunk that normally
- borders the end of the heap (i.e., the high end of the virtual address
- space's data segment).
- @end table
- @end deftp
- @deftypefun {struct mallinfo2} mallinfo2 (void)
- @standards{SVID, malloc.h}
- @safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}}
- @c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified with atomics
- @c but non-atomically elsewhere, may get us inconsistent results. We
- @c mark the statistics as unsafe, rather than the fast-path functions
- @c that collect the possibly inconsistent data.
- @c __libc_mallinfo2 @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock
- @c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem
- @c mutex_lock dup @asulock @aculock
- @c int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena]
- @c malloc_consolidate dup ok
- @c check_malloc_state dup ok/disabled
- @c chunksize dup ok
- @c fastbin dupo ok
- @c bin_at dup ok
- @c last dup ok
- @c mutex_unlock @aculock
- This function returns information about the current dynamic memory usage
- in a structure of type @code{struct mallinfo2}.
- @end deftypefun
- @node Summary of Malloc
- @subsubsection Summary of @code{malloc}-Related Functions
- Here is a summary of the functions that work with @code{malloc}:
- @table @code
- @item void *malloc (size_t @var{size})
- Allocate a block of @var{size} bytes. @xref{Basic Allocation}.
- @item void free (void *@var{addr})
- Free a block previously allocated by @code{malloc}. @xref{Freeing after
- Malloc}.
- @item void *realloc (void *@var{addr}, size_t @var{size})
- Make a block previously allocated by @code{malloc} larger or smaller,
- possibly by copying it to a new location. @xref{Changing Block Size}.
- @item void *reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size})
- Change the size of a block previously allocated by @code{malloc} to
- @code{@var{nmemb} * @var{size}} bytes as with @code{realloc}. @xref{Changing
- Block Size}.
- @item void *calloc (size_t @var{count}, size_t @var{eltsize})
- Allocate a block of @var{count} * @var{eltsize} bytes using
- @code{malloc}, and set its contents to zero. @xref{Allocating Cleared
- Space}.
- @item void *valloc (size_t @var{size})
- Allocate a block of @var{size} bytes, starting on a page boundary.
- @xref{Aligned Memory Blocks}.
- @item void *aligned_alloc (size_t @var{alignment}, size_t @var{size})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
- @item int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
- @item void *memalign (size_t @var{boundary}, size_t @var{size})
- Allocate a block of @var{size} bytes, starting on an address that is a
- multiple of @var{boundary}. @xref{Aligned Memory Blocks}.
- @item int mallopt (int @var{param}, int @var{value})
- Adjust a tunable parameter. @xref{Malloc Tunable Parameters}.
- @item int mcheck (void (*@var{abortfn}) (void))
- Tell @code{malloc} to perform occasional consistency checks on
- dynamically allocated memory, and to call @var{abortfn} when an
- inconsistency is found. @xref{Heap Consistency Checking}.
- @item struct mallinfo2 mallinfo2 (void)
- Return information about the current dynamic memory usage.
- @xref{Statistics of Malloc}.
- @end table
- @node Allocation Debugging
- @subsection Allocation Debugging
- @cindex allocation debugging
- @cindex malloc debugger
- A complicated task when programming with languages which do not use
- garbage collected dynamic memory allocation is to find memory leaks.
- Long running programs must ensure that dynamically allocated objects are
- freed at the end of their lifetime. If this does not happen the system
- runs out of memory, sooner or later.
- The @code{malloc} implementation in @theglibc{} provides some
- simple means to detect such leaks and obtain some information to find
- the location. To do this the application must be started in a special
- mode which is enabled by an environment variable. There are no speed
- penalties for the program if the debugging mode is not enabled.
- @menu
- * Tracing malloc:: How to install the tracing functionality.
- * Using the Memory Debugger:: Example programs excerpts.
- * Tips for the Memory Debugger:: Some more or less clever ideas.
- * Interpreting the traces:: What do all these lines mean?
- @end menu
- @node Tracing malloc
- @subsubsection How to install the tracing functionality
- @deftypefun void mtrace (void)
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}}
- @c Like the mcheck hooks, these are not designed with thread safety in
- @c mind, because the hook pointers are temporarily modified without
- @c regard to other threads, signals or cancellation.
- @c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem
- @c __libc_secure_getenv dup @mtsenv
- @c malloc dup @ascuheap @acsmem
- @c fopen dup @ascuheap @asulock @aculock @acsmem @acsfd
- @c fcntl dup ok
- @c setvbuf dup @aculock
- @c fprintf dup (on newly-created stream) @aculock
- @c __cxa_atexit (once) dup @asulock @aculock @acsmem
- @c free dup @ascuheap @acsmem
- The @code{mtrace} function provides a way to trace memory allocation
- events in the program that calls it. It is disabled by default in the
- library and can be enabled by preloading the debugging library
- @file{libc_malloc_debug} using the @code{LD_PRELOAD} environment
- variable.
- When the @code{mtrace} function is called it looks for an environment
- variable named @code{MALLOC_TRACE}. This variable is supposed to
- contain a valid file name. The user must have write access. If the
- file already exists it is truncated. If the environment variable is not
- set or it does not name a valid file which can be opened for writing
- nothing is done. The behavior of @code{malloc} etc. is not changed.
- For obvious reasons this also happens if the application is installed
- with the SUID or SGID bit set.
- If the named file is successfully opened, @code{mtrace} installs special
- handlers for the functions @code{malloc}, @code{realloc}, and
- @code{free}. From then on, all uses of these functions are traced and
- protocolled into the file. There is now of course a speed penalty for all
- calls to the traced functions so tracing should not be enabled during normal
- use.
- This function is a GNU extension and generally not available on other
- systems. The prototype can be found in @file{mcheck.h}.
- @end deftypefun
- @deftypefun void muntrace (void)
- @standards{GNU, mcheck.h}
- @safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}}
- @c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd
- @c fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt
- @c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd
- The @code{muntrace} function can be called after @code{mtrace} was used
- to enable tracing the @code{malloc} calls. If no (successful) call of
- @code{mtrace} was made @code{muntrace} does nothing.
- Otherwise it deinstalls the handlers for @code{malloc}, @code{realloc},
- and @code{free} and then closes the protocol file. No calls are
- protocolled anymore and the program runs again at full speed.
- This function is a GNU extension and generally not available on other
- systems. The prototype can be found in @file{mcheck.h}.
- @end deftypefun
- @node Using the Memory Debugger
- @subsubsection Example program excerpts
- Even though the tracing functionality does not influence the runtime
- behavior of the program it is not a good idea to call @code{mtrace} in
- all programs. Just imagine that you debug a program using @code{mtrace}
- and all other programs used in the debugging session also trace their
- @code{malloc} calls. The output file would be the same for all programs
- and thus is unusable. Therefore one should call @code{mtrace} only if
- compiled for debugging. A program could therefore start like this:
- @example
- #include <mcheck.h>
- int
- main (int argc, char *argv[])
- @{
- #ifdef DEBUGGING
- mtrace ();
- #endif
- @dots{}
- @}
- @end example
- This is all that is needed if you want to trace the calls during the
- whole runtime of the program. Alternatively you can stop the tracing at
- any time with a call to @code{muntrace}. It is even possible to restart
- the tracing again with a new call to @code{mtrace}. But this can cause
- unreliable results since there may be calls of the functions which are
- not called. Please note that not only the application uses the traced
- functions, also libraries (including the C library itself) use these
- functions.
- This last point is also why it is not a good idea to call @code{muntrace}
- before the program terminates. The libraries are informed about the
- termination of the program only after the program returns from
- @code{main} or calls @code{exit} and so cannot free the memory they use
- before this time.
- So the best thing one can do is to call @code{mtrace} as the very first
- function in the program and never call @code{muntrace}. So the program
- traces almost all uses of the @code{malloc} functions (except those
- calls which are executed by constructors of the program or used
- libraries).
- @node Tips for the Memory Debugger
- @subsubsection Some more or less clever ideas
- You know the situation. The program is prepared for debugging and in
- all debugging sessions it runs well. But once it is started without
- debugging the error shows up. A typical example is a memory leak that
- becomes visible only when we turn off the debugging. If you foresee
- such situations you can still win. Simply use something equivalent to
- the following little program:
- @example
- #include <mcheck.h>
- #include <signal.h>
- static void
- enable (int sig)
- @{
- mtrace ();
- signal (SIGUSR1, enable);
- @}
- static void
- disable (int sig)
- @{
- muntrace ();
- signal (SIGUSR2, disable);
- @}
- int
- main (int argc, char *argv[])
- @{
- @dots{}
- signal (SIGUSR1, enable);
- signal (SIGUSR2, disable);
- @dots{}
- @}
- @end example
- I.e., the user can start the memory debugger any time s/he wants if the
- program was started with @code{MALLOC_TRACE} set in the environment.
- The output will of course not show the allocations which happened before
- the first signal but if there is a memory leak this will show up
- nevertheless.
- @node Interpreting the traces
- @subsubsection Interpreting the traces
- If you take a look at the output it will look similar to this:
- @example
- = Start
- @ [0x8048209] - 0x8064cc8
- @ [0x8048209] - 0x8064ce0
- @ [0x8048209] - 0x8064cf8
- @ [0x80481eb] + 0x8064c48 0x14
- @ [0x80481eb] + 0x8064c60 0x14
- @ [0x80481eb] + 0x8064c78 0x14
- @ [0x80481eb] + 0x8064c90 0x14
- = End
- @end example
- What this all means is not really important since the trace file is not
- meant to be read by a human. Therefore no attention is given to
- readability. Instead there is a program which comes with @theglibc{}
- which interprets the traces and outputs a summary in an
- user-friendly way. The program is called @code{mtrace} (it is in fact a
- Perl script) and it takes one or two arguments. In any case the name of
- the file with the trace output must be specified. If an optional
- argument precedes the name of the trace file this must be the name of
- the program which generated the trace.
- @example
- drepper$ mtrace tst-mtrace log
- No memory leaks.
- @end example
- In this case the program @code{tst-mtrace} was run and it produced a
- trace file @file{log}. The message printed by @code{mtrace} shows there
- are no problems with the code, all allocated memory was freed
- afterwards.
- If we call @code{mtrace} on the example trace given above we would get a
- different output:
- @example
- drepper$ mtrace errlog
- - 0x08064cc8 Free 2 was never alloc'd 0x8048209
- - 0x08064ce0 Free 3 was never alloc'd 0x8048209
- - 0x08064cf8 Free 4 was never alloc'd 0x8048209
- Memory not freed:
- -----------------
- Address Size Caller
- 0x08064c48 0x14 at 0x80481eb
- 0x08064c60 0x14 at 0x80481eb
- 0x08064c78 0x14 at 0x80481eb
- 0x08064c90 0x14 at 0x80481eb
- @end example
- We have called @code{mtrace} with only one argument and so the script
- has no chance to find out what is meant with the addresses given in the
- trace. We can do better:
- @example
- drepper$ mtrace tst errlog
- - 0x08064cc8 Free 2 was never alloc'd /home/drepper/tst.c:39
- - 0x08064ce0 Free 3 was never alloc'd /home/drepper/tst.c:39
- - 0x08064cf8 Free 4 was never alloc'd /home/drepper/tst.c:39
- Memory not freed:
- -----------------
- Address Size Caller
- 0x08064c48 0x14 at /home/drepper/tst.c:33
- 0x08064c60 0x14 at /home/drepper/tst.c:33
- 0x08064c78 0x14 at /home/drepper/tst.c:33
- 0x08064c90 0x14 at /home/drepper/tst.c:33
- @end example
- Suddenly the output makes much more sense and the user can see
- immediately where the function calls causing the trouble can be found.
- Interpreting this output is not complicated. There are at most two
- different situations being detected. First, @code{free} was called for
- pointers which were never returned by one of the allocation functions.
- This is usually a very bad problem and what this looks like is shown in
- the first three lines of the output. Situations like this are quite
- rare and if they appear they show up very drastically: the program
- normally crashes.
- The other situation which is much harder to detect are memory leaks. As
- you can see in the output the @code{mtrace} function collects all this
- information and so can say that the program calls an allocation function
- from line 33 in the source file @file{/home/drepper/tst-mtrace.c} four
- times without freeing this memory before the program terminates.
- Whether this is a real problem remains to be investigated.
- @node Replacing malloc
- @subsection Replacing @code{malloc}
- @cindex @code{malloc} replacement
- @cindex @code{LD_PRELOAD} and @code{malloc}
- @cindex alternative @code{malloc} implementations
- @cindex customizing @code{malloc}
- @cindex interposing @code{malloc}
- @cindex preempting @code{malloc}
- @cindex replacing @code{malloc}
- @Theglibc{} supports replacing the built-in @code{malloc} implementation
- with a different allocator with the same interface. For dynamically
- linked programs, this happens through ELF symbol interposition, either
- using shared object dependencies or @code{LD_PRELOAD}. For static
- linking, the @code{malloc} replacement library must be linked in before
- linking against @code{libc.a} (explicitly or implicitly).
- Care must be taken not to use functionality from @theglibc{} that uses
- @code{malloc} internally. For example, the @code{fopen},
- @code{opendir}, @code{dlopen}, and @code{pthread_setspecific} functions
- currently use the @code{malloc} subsystem internally. If the
- replacement @code{malloc} or its dependencies use thread-local storage
- (TLS), it must use the initial-exec TLS model, and not one of the
- dynamic TLS variants.
- @strong{Note:} Failure to provide a complete set of replacement
- functions (that is, all the functions used by the application,
- @theglibc{}, and other linked-in libraries) can lead to static linking
- failures, and, at run time, to heap corruption and application crashes.
- Replacement functions should implement the behavior documented for
- their counterparts in @theglibc{}; for example, the replacement
- @code{free} should also preserve @code{errno}.
- The minimum set of functions which has to be provided by a custom
- @code{malloc} is given in the table below.
- @table @code
- @item malloc
- @item free
- @item calloc
- @item realloc
- @end table
- These @code{malloc}-related functions are required for @theglibc{} to
- work.@footnote{Versions of @theglibc{} before 2.25 required that a
- custom @code{malloc} defines @code{__libc_memalign} (with the same
- interface as the @code{memalign} function).}
- The @code{malloc} implementation in @theglibc{} provides additional
- functionality not used by the library itself, but which is often used by
- other system libraries and applications. A general-purpose replacement
- @code{malloc} implementation should provide definitions of these
- functions, too. Their names are listed in the following table.
- @table @code
- @item aligned_alloc
- @item free_aligned_sized
- @item free_sized
- @item malloc_usable_size
- @item memalign
- @item posix_memalign
- @item pvalloc
- @item valloc
- @end table
- In addition, very old applications may use the obsolete @code{cfree}
- function.
- Further @code{malloc}-related functions such as @code{mallopt} or
- @code{mallinfo2} will not have any effect or return incorrect statistics
- when a replacement @code{malloc} is in use. However, failure to replace
- these functions typically does not result in crashes or other incorrect
- application behavior, but may result in static linking failures.
- There are other functions (@code{reallocarray}, @code{strdup}, etc.) in
- @theglibc{} that are not listed above but return newly allocated memory to
- callers. Replacement of these functions is not supported and may produce
- incorrect results. @Theglibc{} implementations of these functions call
- the replacement allocator functions whenever available, so they will work
- correctly with @code{malloc} replacement.
- @node Obstacks
- @subsection Obstacks
- @cindex obstacks
- An @dfn{obstack} is a pool of memory containing a stack of objects. You
- can create any number of separate obstacks, and then allocate objects in
- specified obstacks. Within each obstack, the last object allocated must
- always be the first one freed, but distinct obstacks are independent of
- each other.
- Aside from this one constraint of order of freeing, obstacks are totally
- general: an obstack can contain any number of objects of any size. They
- are implemented with macros, so allocation is usually very fast as long as
- the objects are usually small. And the only space overhead per object is
- the padding needed to start each object on a suitable boundary.
- @menu
- * Creating Obstacks:: How to declare an obstack in your program.
- * Preparing for Obstacks:: Preparations needed before you can
- use obstacks.
- * Allocation in an Obstack:: Allocating objects in an obstack.
- * Freeing Obstack Objects:: Freeing objects in an obstack.
- * Obstack Functions:: The obstack functions are both
- functions and macros.
- * Growing Objects:: Making an object bigger by stages.
- * Extra Fast Growing:: Extra-high-efficiency (though more
- complicated) growing objects.
- * Status of an Obstack:: Inquiries about the status of an obstack.
- * Obstacks Data Alignment:: Controlling alignment of objects in obstacks.
- * Obstack Chunks:: How obstacks obtain and release chunks;
- efficiency considerations.
- * Summary of Obstacks::
- @end menu
- @node Creating Obstacks
- @subsubsection Creating Obstacks
- The utilities for manipulating obstacks are declared in the header
- file @file{obstack.h}.
- @pindex obstack.h
- @deftp {Data Type} {struct obstack}
- @standards{GNU, obstack.h}
- An obstack is represented by a data structure of type @code{struct
- obstack}. This structure has a small fixed size; it records the status
- of the obstack and how to find the space in which objects are allocated.
- It does not contain any of the objects themselves. You should not try
- to access the contents of the structure directly; use only the functions
- described in this chapter.
- @end deftp
- You can declare variables of type @code{struct obstack} and use them as
- obstacks, or you can allocate obstacks dynamically like any other kind
- of object. Dynamic allocation of obstacks allows your program to have a
- variable number of different stacks. (You can even allocate an
- obstack structure in another obstack, but this is rarely useful.)
- All the functions that work with obstacks require you to specify which
- obstack to use. You do this with a pointer of type @code{struct obstack
- *}. In the following, we often say ``an obstack'' when strictly
- speaking the object at hand is such a pointer.
- The objects in the obstack are packed into large blocks called
- @dfn{chunks}. The @code{struct obstack} structure points to a chain of
- the chunks currently in use.
- The obstack library obtains a new chunk whenever you allocate an object
- that won't fit in the previous chunk. Since the obstack library manages
- chunks automatically, you don't need to pay much attention to them, but
- you do need to supply a function which the obstack library should use to
- get a chunk. Usually you supply a function which uses @code{malloc}
- directly or indirectly. You must also supply a function to free a chunk.
- These matters are described in the following section.
- @node Preparing for Obstacks
- @subsubsection Preparing for Using Obstacks
- Each source file in which you plan to use the obstack functions
- must include the header file @file{obstack.h}, like this:
- @smallexample
- #include <obstack.h>
- @end smallexample
- @findex obstack_chunk_alloc
- @findex obstack_chunk_free
- Also, if the source file uses the macro @code{obstack_init}, it must
- declare or define two functions or macros that will be called by the
- obstack library. One, @code{obstack_chunk_alloc}, is used to allocate
- the chunks of memory into which objects are packed. The other,
- @code{obstack_chunk_free}, is used to return chunks when the objects in
- them are freed. These macros should appear before any use of obstacks
- in the source file.
- Usually these are defined to use @code{malloc} via the intermediary
- @code{xmalloc} (@pxref{Unconstrained Allocation}). This is done with
- the following pair of macro definitions:
- @smallexample
- #define obstack_chunk_alloc xmalloc
- #define obstack_chunk_free free
- @end smallexample
- @noindent
- Though the memory you get using obstacks really comes from @code{malloc},
- using obstacks is faster because @code{malloc} is called less often, for
- larger blocks of memory. @xref{Obstack Chunks}, for full details.
- At run time, before the program can use a @code{struct obstack} object
- as an obstack, it must initialize the obstack by calling
- @code{obstack_init}.
- @deftypefun int obstack_init (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{@acsmem{}}}
- @c obstack_init @mtsrace:obstack-ptr @acsmem
- @c _obstack_begin @acsmem
- @c chunkfun = obstack_chunk_alloc (suggested malloc)
- @c freefun = obstack_chunk_free (suggested free)
- @c *chunkfun @acsmem
- @c obstack_chunk_alloc user-supplied
- @c *obstack_alloc_failed_handler user-supplied
- @c -> print_and_abort (default)
- @c
- @c print_and_abort
- @c _ dup @ascuintl
- @c fxprintf dup @asucorrupt @aculock @acucorrupt
- @c exit @acucorrupt?
- Initialize obstack @var{obstack-ptr} for allocation of objects. This
- function calls the obstack's @code{obstack_chunk_alloc} function. If
- allocation of memory fails, the function pointed to by
- @code{obstack_alloc_failed_handler} is called. The @code{obstack_init}
- function always returns 1 (Compatibility notice: Former versions of
- obstack returned 0 if allocation failed).
- @end deftypefun
- Here are two examples of how to allocate the space for an obstack and
- initialize it. First, an obstack that is a static variable:
- @smallexample
- static struct obstack myobstack;
- @dots{}
- obstack_init (&myobstack);
- @end smallexample
- @noindent
- Second, an obstack that is itself dynamically allocated:
- @smallexample
- struct obstack *myobstack_ptr
- = (struct obstack *) xmalloc (sizeof (struct obstack));
- obstack_init (myobstack_ptr);
- @end smallexample
- @defvar obstack_alloc_failed_handler
- @standards{GNU, obstack.h}
- The value of this variable is a pointer to a function that
- @code{obstack} uses when @code{obstack_chunk_alloc} fails to allocate
- memory. The default action is to print a message and abort.
- You should supply a function that either calls @code{exit}
- (@pxref{Program Termination}) or @code{longjmp} (@pxref{Non-Local
- Exits}) and doesn't return.
- @smallexample
- void my_obstack_alloc_failed (void)
- @dots{}
- obstack_alloc_failed_handler = &my_obstack_alloc_failed;
- @end smallexample
- @end defvar
- @node Allocation in an Obstack
- @subsubsection Allocation in an Obstack
- @cindex allocation (obstacks)
- The most direct way to allocate an object in an obstack is with
- @code{obstack_alloc}, which is invoked almost like @code{malloc}.
- @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_alloc @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_blank dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- This allocates an uninitialized block of @var{size} bytes in an obstack
- and returns its address. Here @var{obstack-ptr} specifies which obstack
- to allocate the block in; it is the address of the @code{struct obstack}
- object which represents the obstack. Each obstack function or macro
- requires you to specify an @var{obstack-ptr} as the first argument.
- This function calls the obstack's @code{obstack_chunk_alloc} function if
- it needs to allocate a new chunk of memory; it calls
- @code{obstack_alloc_failed_handler} if allocation of memory by
- @code{obstack_chunk_alloc} failed.
- @end deftypefun
- For example, here is a function that allocates a copy of a string @var{str}
- in a specific obstack, which is in the variable @code{string_obstack}:
- @smallexample
- struct obstack string_obstack;
- char *
- copystring (char *string)
- @{
- size_t len = strlen (string) + 1;
- char *s = (char *) obstack_alloc (&string_obstack, len);
- memcpy (s, string, len);
- return s;
- @}
- @end smallexample
- To allocate a block with specified contents, use the function
- @code{obstack_copy}, declared like this:
- @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_copy @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_grow dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- This allocates a block and initializes it by copying @var{size}
- bytes of data starting at @var{address}. It calls
- @code{obstack_alloc_failed_handler} if allocation of memory by
- @code{obstack_chunk_alloc} failed.
- @end deftypefun
- @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_copy0 @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_grow0 dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt
- Like @code{obstack_copy}, but appends an extra byte containing a null
- character. This extra byte is not counted in the argument @var{size}.
- @end deftypefun
- The @code{obstack_copy0} function is convenient for copying a sequence
- of characters into an obstack as a null-terminated string. Here is an
- example of its use:
- @smallexample
- char *
- obstack_savestring (char *addr, int size)
- @{
- return obstack_copy0 (&myobstack, addr, size);
- @}
- @end smallexample
- @noindent
- Contrast this with the previous example of @code{savestring} using
- @code{malloc} (@pxref{Basic Allocation}).
- @node Freeing Obstack Objects
- @subsubsection Freeing Objects in an Obstack
- @cindex freeing (obstacks)
- To free an object allocated in an obstack, use the function
- @code{obstack_free}. Since the obstack is a stack of objects, freeing
- one object automatically frees all other objects allocated more recently
- in the same obstack.
- @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
- @c obstack_free @mtsrace:obstack-ptr @acucorrupt
- @c (obstack_free) @mtsrace:obstack-ptr @acucorrupt
- @c *freefun dup user-supplied
- If @var{object} is a null pointer, everything allocated in the obstack
- is freed. Otherwise, @var{object} must be the address of an object
- allocated in the obstack. Then @var{object} is freed, along with
- everything allocated in @var{obstack-ptr} since @var{object}.
- @end deftypefun
- Note that if @var{object} is a null pointer, the result is an
- uninitialized obstack. To free all memory in an obstack but leave it
- valid for further allocation, call @code{obstack_free} with the address
- of the first object allocated on the obstack:
- @smallexample
- obstack_free (obstack_ptr, first_object_allocated_ptr);
- @end smallexample
- 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 (@pxref{Preparing for Obstacks}). Then other
- obstacks, or non-obstack allocation, can reuse the space of the chunk.
- @node Obstack Functions
- @subsubsection Obstack Functions and Macros
- @cindex macros
- 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 @w{ISO C} and traditional C, but there are
- precautions you must take if you plan to use compilers other than GNU C.
- If you are using an old-fashioned @w{non-ISO 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).
- 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:
- @smallexample
- obstack_alloc (get_obstack (), 4);
- @end smallexample
- @noindent
- you will find that @code{get_obstack} may be called several times.
- If you use @code{*obstack_list_ptr++} as the obstack pointer argument,
- you will get very strange results since the incrementation may occur
- several times.
- In @w{ISO 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:
- @smallexample
- char *x;
- void *(*funcp) ();
- /* @r{Use the macro}. */
- x = (char *) obstack_alloc (obptr, size);
- /* @r{Call the function}. */
- x = (char *) (obstack_alloc) (obptr, size);
- /* @r{Take the address of the function}. */
- funcp = obstack_alloc;
- @end smallexample
- @noindent
- This is the same situation that exists in @w{ISO C} for the standard library
- functions. @xref{Macro Definitions}.
- @strong{Warning:} When you do use the macros, you must observe the
- precaution of avoiding side effects in the first operand, even in @w{ISO C}.
- 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.
- @node Growing Objects
- @subsubsection Growing Objects
- @cindex growing objects (in obstacks)
- @cindex changing the size of a block (obstacks)
- Because memory 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}. The special functions
- for adding data to the growing object are described in this section.
- 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}.
- 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.
- 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.
- @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_blank @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c *chunkfun dup @acsmem
- @c *obstack_alloc_failed_handler dup user-supplied
- @c *freefun
- @c obstack_blank_fast dup @mtsrace:obstack-ptr
- The most basic function for adding to a growing object is
- @code{obstack_blank}, which adds space without initializing it.
- @end deftypefun
- @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c memcpy ok
- To add a block of initialized space, use @code{obstack_grow}, which is
- the growing-object analogue of @code{obstack_copy}. It adds @var{size}
- bytes of data to the growing object, copying the contents from
- @var{data}.
- @end deftypefun
- @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_grow0 @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c (no sequence point between storing NUL and incrementing next_free)
- @c (multiple changes to next_free => @acucorrupt)
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c memcpy ok
- This is the growing-object analogue of @code{obstack_copy0}. It adds
- @var{size} bytes copied from @var{data}, followed by an additional null
- character.
- @end deftypefun
- @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_1grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_1grow_fast dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- To add one character at a time, use the function @code{obstack_1grow}.
- It adds a single byte containing @var{c} to the growing object.
- @end deftypefun
- @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_ptr_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_ptr_grow_fast dup @mtsrace:obstack-ptr
- Adding the value of a pointer one can use the function
- @code{obstack_ptr_grow}. It adds @code{sizeof (void *)} bytes
- containing the value of @var{data}.
- @end deftypefun
- @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_int_grow @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c obstack_int_grow_fast dup @mtsrace:obstack-ptr
- A single value of type @code{int} can be added by using the
- @code{obstack_int_grow} function. It adds @code{sizeof (int)} bytes to
- the growing object and initializes them with the value of @var{data}.
- @end deftypefun
- @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}}
- @c obstack_finish @mtsrace:obstack-ptr @acucorrupt
- When you are finished growing the object, use the function
- @code{obstack_finish} to close it off and return its final address.
- Once you have finished the object, the obstack is available for ordinary
- allocation or for growing another object.
- This function can return a null pointer under the same conditions as
- @code{obstack_alloc} (@pxref{Allocation in an Obstack}).
- @end deftypefun
- 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},
- declared as follows:
- @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- This function returns the current size of the growing object, in bytes.
- Remember to call this function @emph{before} finishing the object.
- After it is finished, @code{obstack_object_size} will return zero.
- @end deftypefun
- If you have started growing an object and wish to cancel it, you should
- finish it and then free it, like this:
- @smallexample
- obstack_free (obstack_ptr, obstack_finish (obstack_ptr));
- @end smallexample
- @noindent
- This has no effect if no object was growing.
- @cindex shrinking objects
- You can use @code{obstack_blank} 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.
- @node Extra Fast Growing
- @subsubsection Extra Fast Growing Objects
- @cindex efficiency and obstacks
- 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.
- 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.
- The function @code{obstack_room} returns the amount of room available
- in the current chunk. It is declared as follows:
- @deftypefun int obstack_room (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- 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-ptr} using the fast growth functions.
- @end deftypefun
- While you know there is room, you can use these fast growth functions
- for adding data to a growing object:
- @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}}
- @c obstack_1grow_fast @mtsrace:obstack-ptr @acucorrupt @acsmem
- @c (no sequence point between copying c and incrementing next_free)
- The function @code{obstack_1grow_fast} adds one byte containing the
- character @var{c} to the growing object in obstack @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_ptr_grow_fast @mtsrace:obstack-ptr
- The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)}
- bytes containing the value of @var{data} to the growing object in
- obstack @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_int_grow_fast @mtsrace:obstack-ptr
- The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes
- containing the value of @var{data} to the growing object in obstack
- @var{obstack-ptr}.
- @end deftypefun
- @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- @c obstack_blank_fast @mtsrace:obstack-ptr
- The function @code{obstack_blank_fast} adds @var{size} bytes to the
- growing object in obstack @var{obstack-ptr} without initializing them.
- @end deftypefun
- When you check for space using @code{obstack_room} 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.
- So, each time you use an ordinary growth function, check afterward for
- sufficient space using @code{obstack_room}. 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.
- Here is an example:
- @smallexample
- @group
- void
- add_string (struct obstack *obstack, const char *ptr, int len)
- @{
- while (len > 0)
- @{
- int room = obstack_room (obstack);
- if (room == 0)
- @{
- /* @r{Not enough room. Add one character slowly,}
- @r{which may copy to a new chunk and make room.} */
- obstack_1grow (obstack, *ptr++);
- len--;
- @}
- else
- @{
- if (room > len)
- room = len;
- /* @r{Add fast as much as we have room for.} */
- len -= room;
- while (room-- > 0)
- obstack_1grow_fast (obstack, *ptr++);
- @}
- @}
- @}
- @end group
- @end smallexample
- @node Status of an Obstack
- @subsubsection Status of an Obstack
- @cindex obstack status
- @cindex status of obstack
- 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.
- @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
- This function returns the tentative address of the beginning of the
- currently growing object in @var{obstack-ptr}. 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!
- 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).
- @end deftypefun
- @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}}
- This function returns the address of the first free byte in the current
- chunk of obstack @var{obstack-ptr}. This is the end of the currently
- growing object. If no object is growing, @code{obstack_next_free}
- returns the same value as @code{obstack_base}.
- @end deftypefun
- @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @c dup
- @safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}}
- This function returns the size in bytes of the currently growing object.
- This is equivalent to
- @smallexample
- obstack_next_free (@var{obstack-ptr}) - obstack_base (@var{obstack-ptr})
- @end smallexample
- @end deftypefun
- @node Obstacks Data Alignment
- @subsubsection Alignment of Data in Obstacks
- @cindex alignment (in obstacks)
- Each obstack has an @dfn{alignment boundary}; each object allocated in
- the obstack automatically starts on an address that is a multiple of the
- specified boundary. By default, this boundary is aligned so that
- the object can hold any type of data.
- To access an obstack's alignment boundary, use the macro
- @code{obstack_alignment_mask}, whose function prototype looks like
- this:
- @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- The value is a bit mask; a bit that is 1 indicates that the corresponding
- bit in the address of an object should be 0. The mask value should be one
- less than a power of 2; the effect is that all object addresses are
- multiples of that power of 2. The default value of the mask is a value
- that allows aligned objects to hold any type of data: for example, if
- its value is 3, any type of data can be stored at locations whose
- addresses are multiples of 4. A mask value of 0 means an object can start
- on any multiple of 1 (that is, no alignment is required).
- The expansion of the macro @code{obstack_alignment_mask} is an lvalue,
- so you can alter the mask by assignment. For example, this statement:
- @smallexample
- obstack_alignment_mask (obstack_ptr) = 0;
- @end smallexample
- @noindent
- has the effect of turning off alignment processing in the specified obstack.
- @end deftypefn
- Note that a change in alignment mask does not take effect until
- @emph{after} the next time an object is allocated or finished in the
- obstack. If you are not growing an object, you can make the new
- alignment mask take effect immediately by calling @code{obstack_finish}.
- This will finish a zero-length object and then do proper alignment for
- the next object.
- @node Obstack Chunks
- @subsubsection Obstack Chunks
- @cindex efficiency of chunks
- @cindex chunks
- Obstacks work by allocating space for themselves in large chunks, and
- then parceling out space in the chunks to satisfy your requests. Chunks
- are normally 4096 bytes long unless you specify a different chunk size.
- The chunk size includes 8 bytes of overhead that are not actually used
- for storing objects. Regardless of the specified size, longer chunks
- will be allocated when necessary for long objects.
- The obstack library allocates chunks by calling the function
- @code{obstack_chunk_alloc}, which you must define. When a chunk is no
- longer needed because you have freed all the objects in it, the obstack
- library frees the chunk by calling @code{obstack_chunk_free}, which you
- must also define.
- These two must be defined (as macros) or declared (as functions) in each
- source file that uses @code{obstack_init} (@pxref{Creating Obstacks}).
- Most often they are defined as macros like this:
- @smallexample
- #define obstack_chunk_alloc malloc
- #define obstack_chunk_free free
- @end smallexample
- Note that these are simple macros (no arguments). Macro definitions with
- arguments will not work! It is necessary that @code{obstack_chunk_alloc}
- or @code{obstack_chunk_free}, alone, expand into a function name if it is
- not itself a function name.
- If you allocate chunks with @code{malloc}, the chunk size should be a
- power of 2. The default chunk size, 4096, was chosen because it is long
- enough to satisfy many typical requests on the obstack yet short enough
- not to waste too much memory in the portion of the last chunk not yet used.
- @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr})
- @standards{GNU, obstack.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This returns the chunk size of the given obstack.
- @end deftypefn
- Since this macro expands to an lvalue, you can specify a new chunk size by
- assigning it a new value. Doing so does not affect the chunks already
- allocated, but will change the size of chunks allocated for that particular
- obstack in the future. It is unlikely to be useful to make the chunk size
- smaller, but making it larger might improve efficiency if you are
- allocating many objects whose size is comparable to the chunk size. Here
- is how to do so cleanly:
- @smallexample
- if (obstack_chunk_size (obstack_ptr) < @var{new-chunk-size})
- obstack_chunk_size (obstack_ptr) = @var{new-chunk-size};
- @end smallexample
- @node Summary of Obstacks
- @subsubsection Summary of Obstack Functions
- Here is a summary of all the functions associated with obstacks. Each
- takes the address of an obstack (@code{struct obstack *}) as its first
- argument.
- @table @code
- @item void obstack_init (struct obstack *@var{obstack-ptr})
- Initialize use of an obstack. @xref{Creating Obstacks}.
- @item void *obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size})
- Allocate an object of @var{size} uninitialized bytes.
- @xref{Allocation in an Obstack}.
- @item void *obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Allocate an object of @var{size} bytes, with contents copied from
- @var{address}. @xref{Allocation in an Obstack}.
- @item void *obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Allocate an object of @var{size}+1 bytes, with @var{size} of them copied
- from @var{address}, followed by a null character at the end.
- @xref{Allocation in an Obstack}.
- @item void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object})
- Free @var{object} (and everything allocated in the specified obstack
- more recently than @var{object}). @xref{Freeing Obstack Objects}.
- @item void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size})
- Add @var{size} uninitialized bytes to a growing object.
- @xref{Growing Objects}.
- @item void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Add @var{size} bytes, copied from @var{address}, to a growing object.
- @xref{Growing Objects}.
- @item void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size})
- Add @var{size} bytes, copied from @var{address}, to a growing object,
- and then add another byte containing a null character. @xref{Growing
- Objects}.
- @item void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{data-char})
- Add one byte containing @var{data-char} to a growing object.
- @xref{Growing Objects}.
- @item void *obstack_finish (struct obstack *@var{obstack-ptr})
- Finalize the object that is growing and return its permanent address.
- @xref{Growing Objects}.
- @item int obstack_object_size (struct obstack *@var{obstack-ptr})
- Get the current size of the currently growing object. @xref{Growing
- Objects}.
- @item void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size})
- Add @var{size} uninitialized bytes to a growing object without checking
- that there is enough room. @xref{Extra Fast Growing}.
- @item void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{data-char})
- Add one byte containing @var{data-char} to a growing object without
- checking that there is enough room. @xref{Extra Fast Growing}.
- @item int obstack_room (struct obstack *@var{obstack-ptr})
- Get the amount of room now available for growing the current object.
- @xref{Extra Fast Growing}.
- @item int obstack_alignment_mask (struct obstack *@var{obstack-ptr})
- The mask used for aligning the beginning of an object. This is an
- lvalue. @xref{Obstacks Data Alignment}.
- @item int obstack_chunk_size (struct obstack *@var{obstack-ptr})
- The size for allocating chunks. This is an lvalue. @xref{Obstack Chunks}.
- @item void *obstack_base (struct obstack *@var{obstack-ptr})
- Tentative starting address of the currently growing object.
- @xref{Status of an Obstack}.
- @item void *obstack_next_free (struct obstack *@var{obstack-ptr})
- Address just after the end of the currently growing object.
- @xref{Status of an Obstack}.
- @end table
- @node Variable Size Automatic
- @subsection Automatic Storage with Variable Size
- @cindex automatic freeing
- @cindex @code{alloca} function
- @cindex automatic storage with variable size
- The function @code{alloca} supports a kind of half-dynamic allocation in
- which blocks are allocated dynamically but freed automatically.
- Allocating a block with @code{alloca} is an explicit action; you can
- allocate as many blocks as you wish, and compute the size at run time. But
- all the blocks are freed when you exit the function that @code{alloca} was
- called from, just as if they were automatic variables declared in that
- function. There is no way to free the space explicitly.
- The prototype for @code{alloca} is in @file{stdlib.h}. This function is
- a BSD extension.
- @pindex stdlib.h
- @deftypefun {void *} alloca (size_t @var{size})
- @standards{GNU, stdlib.h}
- @standards{BSD, stdlib.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- The return value of @code{alloca} is the address of a block of @var{size}
- bytes of memory, allocated in the stack frame of the calling function.
- @end deftypefun
- Do not use @code{alloca} inside the arguments of a function call---you
- will get unpredictable results, because the stack space for the
- @code{alloca} would appear on the stack in the middle of the space for
- the function arguments. An example of what to avoid is @code{foo (x,
- alloca (4), y)}.
- @c This might get fixed in future versions of GCC, but that won't make
- @c it safe with compilers generally.
- @menu
- * Alloca Example:: Example of using @code{alloca}.
- * Advantages of Alloca:: Reasons to use @code{alloca}.
- * Disadvantages of Alloca:: Reasons to avoid @code{alloca}.
- * GNU C Variable-Size Arrays:: Only in GNU C, here is an alternative
- method of allocating dynamically and
- freeing automatically.
- @end menu
- @node Alloca Example
- @subsubsection @code{alloca} Example
- As an example of the use of @code{alloca}, here is a function that opens
- a file name made from concatenating two argument strings, and returns a
- file descriptor or minus one signifying failure:
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
- @}
- @end smallexample
- @noindent
- Here is how you would get the same results with @code{malloc} and
- @code{free}:
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = malloc (strlen (str1) + strlen (str2) + 1);
- int desc;
- if (name == 0)
- fatal ("virtual memory exceeded");
- stpcpy (stpcpy (name, str1), str2);
- desc = open (name, flags, mode);
- free (name);
- return desc;
- @}
- @end smallexample
- As you can see, it is simpler with @code{alloca}. But @code{alloca} has
- other, more important advantages, and some disadvantages.
- @node Advantages of Alloca
- @subsubsection Advantages of @code{alloca}
- Here are the reasons why @code{alloca} may be preferable to @code{malloc}:
- @itemize @bullet
- @item
- Using @code{alloca} wastes very little space and is very fast. (It is
- open-coded by the GNU C compiler.)
- @item
- Since @code{alloca} does not have separate pools for different sizes of
- blocks, space used for any size block can be reused for any other size.
- @code{alloca} does not cause memory fragmentation.
- @item
- @cindex longjmp
- Nonlocal exits done with @code{longjmp} (@pxref{Non-Local Exits})
- automatically free the space allocated with @code{alloca} when they exit
- through the function that called @code{alloca}. This is the most
- important reason to use @code{alloca}.
- To illustrate this, suppose you have a function
- @code{open_or_report_error} which returns a descriptor, like
- @code{open}, if it succeeds, but does not return to its caller if it
- fails. If the file cannot be opened, it prints an error message and
- jumps out to the command level of your program using @code{longjmp}.
- Let's change @code{open2} (@pxref{Alloca Example}) to use this
- subroutine:
- @smallexample
- int
- open2 (char *str1, char *str2, int flags, int mode)
- @{
- char *name = (char *) alloca (strlen (str1) + strlen (str2) + 1);
- stpcpy (stpcpy (name, str1), str2);
- return open_or_report_error (name, flags, mode);
- @}
- @end smallexample
- @noindent
- Because of the way @code{alloca} works, the memory it allocates is
- freed even when an error occurs, with no special effort required.
- By contrast, the previous definition of @code{open2} (which uses
- @code{malloc} and @code{free}) would develop a memory leak if it were
- changed in this way. Even if you are willing to make more changes to
- fix it, there is no easy way to do so.
- @end itemize
- @node Disadvantages of Alloca
- @subsubsection Disadvantages of @code{alloca}
- @cindex @code{alloca} disadvantages
- @cindex disadvantages of @code{alloca}
- These are the disadvantages of @code{alloca} in comparison with
- @code{malloc}:
- @itemize @bullet
- @item
- If you try to allocate more memory than the machine can provide, you
- don't get a clean error message. Instead you get a fatal signal like
- the one you would get from an infinite recursion; probably a
- segmentation violation (@pxref{Program Error Signals}).
- @item
- Some @nongnusystems{} fail to support @code{alloca}, so it is less
- portable. However, a slower emulation of @code{alloca} written in C
- is available for use on systems with this deficiency.
- @end itemize
- @node GNU C Variable-Size Arrays
- @subsubsection GNU C Variable-Size Arrays
- @cindex variable-sized arrays
- In GNU C, you can replace most uses of @code{alloca} with an array of
- variable size. Here is how @code{open2} would look then:
- @smallexample
- int open2 (char *str1, char *str2, int flags, int mode)
- @{
- char name[strlen (str1) + strlen (str2) + 1];
- stpcpy (stpcpy (name, str1), str2);
- return open (name, flags, mode);
- @}
- @end smallexample
- But @code{alloca} is not always equivalent to a variable-sized array, for
- several reasons:
- @itemize @bullet
- @item
- A variable size array's space is freed at the end of the scope of the
- name of the array. The space allocated with @code{alloca}
- remains until the end of the function.
- @item
- It is possible to use @code{alloca} within a loop, allocating an
- additional block on each iteration. This is impossible with
- variable-sized arrays.
- @end itemize
- @strong{NB:} If you mix use of @code{alloca} and variable-sized arrays
- within one function, exiting a scope in which a variable-sized array was
- declared frees all blocks allocated with @code{alloca} during the
- execution of that scope.
- @node Resizing the Data Segment
- @section Resizing the Data Segment
- The symbols in this section are declared in @file{unistd.h}.
- You will not normally use the functions in this section, because the
- functions described in @ref{Memory Allocation} are easier to use. Those
- are interfaces to a @glibcadj{} memory allocator that uses the
- functions below itself. The functions below are simple interfaces to
- system calls.
- @deftypefun int brk (void *@var{addr})
- @standards{BSD, unistd.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{brk} sets the high end of the calling process' data segment to
- @var{addr}.
- The address of the end of a segment is defined to be the address of the
- last byte in the segment plus 1.
- The function has no effect if @var{addr} is lower than the low end of
- the data segment. (This is considered success, by the way.)
- The function fails if it would cause the data segment to overlap another
- segment or exceed the process' data storage limit (@pxref{Limits on
- Resources}).
- The function is named for a common historical case where data storage
- and the stack are in the same segment. Data storage allocation grows
- upward from the bottom of the segment while the stack grows downward
- toward it from the top of the segment and the curtain between them is
- called the @dfn{break}.
- The return value is zero on success. On failure, the return value is
- @code{-1} and @code{errno} is set accordingly. The following @code{errno}
- values are specific to this function:
- @table @code
- @item ENOMEM
- The request would cause the data segment to overlap another segment or
- exceed the process' data storage limit.
- @end table
- @c The Brk system call in Linux (as opposed to the GNU C Library function)
- @c is considerably different. It always returns the new end of the data
- @c segment, whether it succeeds or fails. The GNU C library Brk determines
- @c it's a failure if and only if the system call returns an address less
- @c than the address requested.
- @end deftypefun
- @deftypefun {void *} sbrk (ptrdiff_t @var{delta})
- @standards{BSD, unistd.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This function is the same as @code{brk} except that you specify the new
- end of the data segment as an offset @var{delta} from the current end
- and on success the return value is the address of the resulting end of
- the data segment instead of zero.
- This means you can use @samp{sbrk(0)} to find out what the current end
- of the data segment is.
- @end deftypefun
- @node Memory Protection
- @section Memory Protection
- @cindex memory protection
- @cindex page protection
- @cindex protection flags
- When a page is mapped using @code{mmap}, page protection flags can be
- specified using the protection flags argument. @xref{Memory-mapped
- I/O}.
- The following flags are available:
- @vtable @code
- @item PROT_WRITE
- @standards{POSIX, sys/mman.h}
- The memory can be written to.
- @item PROT_READ
- @standards{POSIX, sys/mman.h}
- The memory can be read. On some architectures, this flag implies that
- the memory can be executed as well (as if @code{PROT_EXEC} had been
- specified at the same time).
- @item PROT_EXEC
- @standards{POSIX, sys/mman.h}
- The memory can be used to store instructions which can then be executed.
- On most architectures, this flag implies that the memory can be read (as
- if @code{PROT_READ} had been specified).
- @item PROT_NONE
- @standards{POSIX, sys/mman.h}
- This flag must be specified on its own.
- The memory is reserved, but cannot be read, written, or executed. If
- this flag is specified in a call to @code{mmap}, a virtual memory area
- will be set aside for future use in the process, and @code{mmap} calls
- without the @code{MAP_FIXED} flag will not use it for subsequent
- allocations. For anonymous mappings, the kernel will not reserve any
- physical memory for the allocation at the time the mapping is created.
- @end vtable
- The operating system may keep track of these flags separately even if
- the underlying hardware treats them the same for the purposes of access
- checking (as happens with @code{PROT_READ} and @code{PROT_EXEC} on some
- platforms). On GNU systems, @code{PROT_EXEC} always implies
- @code{PROT_READ}, so that users can view the machine code which is
- executing on their system.
- Inappropriate access will cause a segfault (@pxref{Program Error
- Signals}).
- After allocation, protection flags can be changed using the
- @code{mprotect} function.
- @deftypefun int mprotect (void *@var{address}, size_t @var{length}, int @var{protection})
- @standards{POSIX, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- A successful call to the @code{mprotect} function changes the protection
- flags of at least @var{length} bytes of memory, starting at
- @var{address}.
- @var{address} must be aligned to the page size for the mapping. The
- system page size can be obtained by calling @code{sysconf} with the
- @code{_SC_PAGESIZE} parameter (@pxref{Sysconf Definition}). The system
- page size is the granularity in which the page protection of anonymous
- memory mappings and most file mappings can be changed. Memory which is
- mapped from special files or devices may have larger page granularity
- than the system page size and may require larger alignment.
- @var{length} is the number of bytes whose protection flags must be
- changed. It is automatically rounded up to the next multiple of the
- system page size.
- @var{protection} is a combination of the @code{PROT_*} flags described
- above.
- The @code{mprotect} function returns @math{0} on success and @math{-1}
- on failure.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item ENOMEM
- The system was not able to allocate resources to fulfill the request.
- This can happen if there is not enough physical memory in the system for
- the allocation of backing storage. The error can also occur if the new
- protection flags would cause the memory region to be split from its
- neighbors, and the process limit for the number of such distinct memory
- regions would be exceeded.
- @item EINVAL
- @var{address} is not properly aligned to a page boundary for the
- mapping, or @var{length} (after rounding up to the system page size) is
- not a multiple of the applicable page size for the mapping, or the
- combination of flags in @var{protection} is not valid.
- @item EACCES
- The file for a file-based mapping was not opened with open flags which
- are compatible with @var{protection}.
- @item EPERM
- The system security policy does not allow a mapping with the specified
- flags. For example, mappings which are both @code{PROT_EXEC} and
- @code{PROT_WRITE} at the same time might not be allowed.
- @end table
- @end deftypefun
- If the @code{mprotect} function is used to make a region of memory
- inaccessible by specifying the @code{PROT_NONE} protection flag and
- access is later restored, the memory retains its previous contents.
- On some systems, it may not be possible to specify additional flags
- which were not present when the mapping was first created. For example,
- an attempt to make a region of memory executable could fail if the
- initial protection flags were @samp{PROT_READ | PROT_WRITE}.
- In general, the @code{mprotect} function can be used to change any
- process memory, no matter how it was allocated. However, portable use
- of the function requires that it is only used with memory regions
- returned by @code{mmap} or @code{mmap64}.
- @deftypefun int mseal (void *@var{address}, size_t @var{length}, unsigned long @var{flags})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- A successful call to the @code {mseal} function protects the memory
- range @var{address} of @var{length} bytes, previously allocated with
- @code{mmap} or @code{mremap}, against further metadata changes, such
- as:
- @itemize @bullet
- @item
- Unmapping, moving to another location, extending or shrinking the size,
- via @code{munmap} and @code{mremap}.
- @item
- Moving or expanding a different VMA into the current location, via
- @code{mremap}.
- @item
- Modifying the memory range with @code{mmap} along with the flag @code{MAP_FIXED}.
- @item
- Change the protection flags with @code{mprotect} or @code{pkey_mprotect}. Also
- for certain destructive @code{madvise} behaviours (@code{MADV_DONTNEED},
- @code{MADV_FREE}, @code{MADV_DONTNEED_LOCKED}, and @code{MADV_WIPEONFORK}),
- @code{mseal} only blocks the operation if the protection key associated with
- the memory denies write.
- @item
- Destructive behaviors on anonymous memory, such as @code{madvise} with
- @code{MADV_DONTNEED}.
- @end itemize
- The @var{address} must be an allocated virtual memory done by @code{mmap}
- or @code{mremap}, and it must be page-aligned. The end address (@var{address}
- plus @var{length}) must be within an allocated virtual memory range. There
- should be no unallocated memory between the start and end of the address range.
- The @var{flags} is currently unused.
- The @code{mseal} function returns @math{0} on success and @math{-1} on
- failure.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item EPERM
- The system blocked the operation, and the given address range is unmodified
- without a partial update. This error is also returned when @code{mseal} is
- issued on a 32-bit CPU (sealing is currently supported only on 64-bit CPUs,
- although 32-bit binaries running on a 64-bit kernel are supported).
- @item ENOMEM
- Either the @var{address} is not allocated, or the end address is not within the
- allocation, or there is unallocated memory between the start and end address.
- @item ENOSYS
- The kernel does not support the @code{mseal} syscall.
- @end table
- @end deftypefun
- @strong{NB:} The memory sealing changes the lifetime of a mapping, where the
- sealing memory could not be unmapped until the process terminates or replaces
- the process image through @code{execve} function. The sealed mappings are
- inherited through @code{fork}.
- @subsection Memory Protection Keys
- @cindex memory protection key
- @cindex protection key
- @cindex MPK
- On some systems, further access restrictions can be added to specific pages
- using @dfn{memory protection keys}. These restrictions work as follows:
- @itemize @bullet
- @item
- All memory pages are associated with a protection key. The default
- protection key does not cause any additional protections to be applied
- during memory accesses. New keys can be allocated with the
- @code{pkey_alloc} function, and applied to pages using
- @code{pkey_mprotect}.
- @item
- Each thread has a set of separate access restrictions for each
- protection key. These access restrictions can be manipulated using the
- @code{pkey_set} and @code{pkey_get} functions.
- @item
- During a memory access, the system obtains the protection key for the
- accessed page and uses that to determine the applicable access restrictions,
- as configured for the current thread. If the access is restricted, a
- segmentation fault is the result ((@pxref{Program Error Signals}).
- These checks happen in addition to the @code{PROT_}* protection flags
- set by @code{mprotect} or @code{pkey_mprotect}.
- @end itemize
- New threads and subprocesses inherit the access restrictions of the current
- thread. If a protection key is allocated subsequently, existing threads
- (except the current) will use an unspecified system default for the
- access restrictions associated with newly allocated keys.
- Upon entering a signal handler, the system resets the access restrictions of
- the current thread so that pages with the default key can be accessed,
- but the access restrictions for other protection keys are unspecified.
- Applications are expected to allocate a key once using
- @code{pkey_alloc}, and apply the key to memory regions which need
- special protection with @code{pkey_mprotect}:
- @smallexample
- int key = pkey_alloc (0, PKEY_DISABLE_ACCESS);
- if (key < 0)
- /* Perform error checking, including fallback for lack of support. */
- ...;
- /* Apply the key to a special memory region used to store critical
- data. */
- if (pkey_mprotect (region, region_length,
- PROT_READ | PROT_WRITE, key) < 0)
- ...; /* Perform error checking (generally fatal). */
- @end smallexample
- If the key allocation fails due to lack of support for memory protection
- keys, the @code{pkey_mprotect} call can usually be skipped. In this
- case, the region will not be protected by default. It is also possible
- to call @code{pkey_mprotect} with a key value of @math{-1}, in which
- case it will behave in the same way as @code{mprotect}.
- After key allocation assignment to memory pages, @code{pkey_set} can be
- used to temporarily acquire access to the memory region and relinquish
- it again:
- @smallexample
- if (key >= 0 && pkey_set (key, PKEY_UNRESTRICTED) < 0)
- ...; /* Perform error checking (generally fatal). */
- /* At this point, the current thread has read-write access to the
- memory region. */
- ...
- /* Revoke access again. */
- if (key >= 0 && pkey_set (key, PKEY_DISABLE_ACCESS) < 0)
- ...; /* Perform error checking (generally fatal). */
- @end smallexample
- In this example, a negative key value indicates that no key had been
- allocated, which means that the system lacks support for memory
- protection keys and it is not necessary to change the the access restrictions
- of the current thread (because it always has access).
- Compared to using @code{mprotect} to change the page protection flags,
- this approach has two advantages: It is thread-safe in the sense that
- the access restrictions are only changed for the current thread, so another
- thread which changes its own access restrictions concurrently to gain access
- to the mapping will not suddenly see its access restrictions updated. And
- @code{pkey_set} typically does not involve a call into the kernel and a
- context switch, so it is more efficient.
- @deftypefun int pkey_alloc (unsigned int @var{flags}, unsigned int @var{access_restrictions})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
- Allocate a new protection key. The @var{flags} argument is reserved and
- must be zero. The @var{access_restrictions} argument specifies access restrictions
- which are applied to the current thread (as if with @code{pkey_set}
- below). Access restrictions of other threads are not changed.
- The function returns the new protection key, a non-negative number, or
- @math{-1} on error.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item ENOSYS
- The system does not implement memory protection keys.
- @item EINVAL
- The @var{flags} argument is not zero.
- The @var{access_restrictions} argument is invalid.
- The system does not implement memory protection keys or runs in a mode
- in which memory protection keys are disabled.
- @item ENOSPC
- All available protection keys already have been allocated.
- The system does not implement memory protection keys or runs in a mode
- in which memory protection keys are disabled.
- @end table
- @end deftypefun
- @deftypefun int pkey_free (int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Deallocate the protection key, so that it can be reused by
- @code{pkey_alloc}.
- Calling this function does not change the access restrictions of the freed
- protection key. The calling thread and other threads may retain access
- to it, even if it is subsequently allocated again. For this reason, it
- is not recommended to call the @code{pkey_free} function.
- @table @code
- @item ENOSYS
- The system does not implement memory protection keys.
- @item EINVAL
- The @var{key} argument is not a valid protection key.
- @end table
- @end deftypefun
- @deftypefun int pkey_mprotect (void *@var{address}, size_t @var{length}, int @var{protection}, int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Similar to @code{mprotect}, but also set the memory protection key for
- the memory region to @code{key}.
- Some systems use memory protection keys to emulate certain combinations
- of @var{protection} flags. Under such circumstances, specifying an
- explicit protection key may behave as if additional flags have been
- specified in @var{protection}, even though this does not happen with the
- default protection key. For example, some systems can support
- @code{PROT_EXEC}-only mappings only with a default protection key, and
- memory with a key which was allocated using @code{pkey_alloc} will still
- be readable if @code{PROT_EXEC} is specified without @code{PROT_READ}.
- If @var{key} is @math{-1}, the default protection key is applied to the
- mapping, just as if @code{mprotect} had been called.
- The @code{pkey_mprotect} function returns @math{0} on success and
- @math{-1} on failure. The same @code{errno} error conditions as for
- @code{mprotect} are defined for this function, with the following
- addition:
- @table @code
- @item EINVAL
- The @var{key} argument is not @math{-1} or a valid memory protection
- key allocated using @code{pkey_alloc}.
- @item ENOSYS
- The system does not implement memory protection keys, and @var{key} is
- not @math{-1}.
- @end table
- @end deftypefun
- @deftypefun int pkey_set (int @var{key}, unsigned int @var{access_restrictions})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Change the access restrictions of the current thread for memory pages with
- the protection key @var{key} to @var{access_restrictions}. If
- @var{access_restrictions} is @code{PKEY_UNRESTRICTED} (zero), no additional
- access restrictions on top of the page protection flags are applied. Otherwise,
- @var{access_restrictions} is a combination of the following flags:
- @vtable @code
- @item PKEY_DISABLE_READ
- @standards{Linux, sys/mman.h}
- Subsequent attempts to read from memory with the specified protection
- key will fault. At present only AArch64 platforms with enabled Stage 1
- permission overlays feature support this type of restriction.
- @item PKEY_DISABLE_WRITE
- @standards{Linux, sys/mman.h}
- Subsequent attempts to write to memory with the specified protection
- key will fault.
- @item PKEY_DISABLE_ACCESS
- @standards{Linux, sys/mman.h}
- Subsequent attempts to write to or read from memory with the specified
- protection key will fault. On AArch64 platforms with enabled Stage 1
- permission overlays feature this restriction value has the same effect
- as combination of @code{PKEY_DISABLE_READ} and @code{PKEY_DISABLE_WRITE}.
- @item PKEY_DISABLE_EXECUTE
- @standards{Linux, sys/mman.h}
- Subsequent attempts to execute from memory with the specified protection
- key will fault. At present only AArch64 platforms with enabled Stage 1
- permission overlays feature support this type of restriction.
- @end vtable
- Operations not specified as flags are not restricted. In particular,
- this means that the memory region will remain executable if it was
- mapped with the @code{PROT_EXEC} protection flag and
- @code{PKEY_DISABLE_ACCESS} has been specified.
- Calling the @code{pkey_set} function with a protection key which was not
- allocated by @code{pkey_alloc} results in undefined behavior. This
- means that calling this function on systems which do not support memory
- protection keys is undefined.
- The @code{pkey_set} function returns @math{0} on success and @math{-1}
- on failure.
- The following @code{errno} error conditions are defined for this
- function:
- @table @code
- @item EINVAL
- The system does not support the access restrictions expressed in
- the @var{access_restrictions} argument.
- @end table
- @end deftypefun
- @deftypefun int pkey_get (int @var{key})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- Return the access restrictions of the current thread for memory pages
- with protection key @var{key}. The return value is zero or a combination of
- the @code{PKEY_DISABLE_}* flags; see the @code{pkey_set} function.
- The returned value should be checked for presence or absence of specific flags
- using bitwise operations. Comparing the returned value with any of the flags
- or their combination using equals will almost certainly fail.
- Calling the @code{pkey_get} function with a protection key which was not
- allocated by @code{pkey_alloc} results in undefined behavior. This
- means that calling this function on systems which do not support memory
- protection keys is undefined.
- @end deftypefun
- @node Locking Pages
- @section Locking Pages
- @cindex locking pages
- @cindex memory lock
- @cindex paging
- You can tell the system to associate a particular virtual memory page
- with a real page frame and keep it that way --- i.e., cause the page to
- be paged in if it isn't already and mark it so it will never be paged
- out and consequently will never cause a page fault. This is called
- @dfn{locking} a page.
- The functions in this chapter lock and unlock the calling process'
- pages.
- @menu
- * Why Lock Pages:: Reasons to read this section.
- * Locked Memory Details:: Everything you need to know locked
- memory
- * Page Lock Functions:: Here's how to do it.
- @end menu
- @node Why Lock Pages
- @subsection Why Lock Pages
- Because page faults cause paged out pages to be paged in transparently,
- a process rarely needs to be concerned about locking pages. However,
- there are two reasons people sometimes are:
- @itemize @bullet
- @item
- Speed. A page fault is transparent only insofar as the process is not
- sensitive to how long it takes to do a simple memory access. Time-critical
- processes, especially realtime processes, may not be able to wait or
- may not be able to tolerate variance in execution speed.
- @cindex realtime processing
- @cindex speed of execution
- A process that needs to lock pages for this reason probably also needs
- priority among other processes for use of the CPU. @xref{Priority}.
- In some cases, the programmer knows better than the system's demand
- paging allocator which pages should remain in real memory to optimize
- system performance. In this case, locking pages can help.
- @item
- Privacy. If you keep secrets in virtual memory and that virtual memory
- gets paged out, that increases the chance that the secrets will get out.
- If a passphrase gets written out to disk swap space, for example, it might
- still be there long after virtual and real memory have been wiped clean.
- @end itemize
- Be aware that when you lock a page, that's one fewer page frame that can
- be used to back other virtual memory (by the same or other processes),
- which can mean more page faults, which means the system runs more
- slowly. In fact, if you lock enough memory, some programs may not be
- able to run at all for lack of real memory.
- @node Locked Memory Details
- @subsection Locked Memory Details
- A memory lock is associated with a virtual page, not a real frame. The
- paging rule is: If a frame backs at least one locked page, don't page it
- out.
- Memory locks do not stack. I.e., you can't lock a particular page twice
- so that it has to be unlocked twice before it is truly unlocked. It is
- either locked or it isn't.
- A memory lock persists until the process that owns the memory explicitly
- unlocks it. (But process termination and exec cause the virtual memory
- to cease to exist, which you might say means it isn't locked any more).
- Memory locks are not inherited by child processes. (But note that on a
- modern Unix system, immediately after a fork, the parent's and the
- child's virtual address space are backed by the same real page frames,
- so the child enjoys the parent's locks). @xref{Creating a Process}.
- Because of its ability to impact other processes, only the superuser can
- lock a page. Any process can unlock its own page.
- The system sets limits on the amount of memory a process can have locked
- and the amount of real memory it can have dedicated to it. @xref{Limits
- on Resources}.
- In Linux, locked pages aren't as locked as you might think.
- Two virtual pages that are not shared memory can nonetheless be backed
- by the same real frame. The kernel does this in the name of efficiency
- when it knows both virtual pages contain identical data, and does it
- even if one or both of the virtual pages are locked.
- But when a process modifies one of those pages, the kernel must get it a
- separate frame and fill it with the page's data. This is known as a
- @dfn{copy-on-write page fault}. It takes a small amount of time and in
- a pathological case, getting that frame may require I/O.
- @cindex copy-on-write page fault
- @cindex page fault, copy-on-write
- To make sure this doesn't happen to your program, don't just lock the
- pages. Write to them as well, unless you know you won't write to them
- ever. And to make sure you have pre-allocated frames for your stack,
- enter a scope that declares a C automatic variable larger than the
- maximum stack size you will need, set it to something, then return from
- its scope.
- @node Page Lock Functions
- @subsection Functions To Lock And Unlock Pages
- The symbols in this section are declared in @file{sys/mman.h}. These
- functions are defined by POSIX.1b, but their availability depends on
- your kernel. If your kernel doesn't allow these functions, they exist
- but always fail. They @emph{are} available with a Linux kernel.
- @strong{Portability Note:} POSIX.1b requires that when the @code{mlock}
- and @code{munlock} functions are available, the file @file{unistd.h}
- define the macro @code{_POSIX_MEMLOCK_RANGE} and the file
- @code{limits.h} define the macro @code{PAGESIZE} to be the size of a
- memory page in bytes. It requires that when the @code{mlockall} and
- @code{munlockall} functions are available, the @file{unistd.h} file
- define the macro @code{_POSIX_MEMLOCK}. @Theglibc{} conforms to
- this requirement.
- @deftypefun int mlock (const void *@var{addr}, size_t @var{len})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{mlock} locks a range of the calling process' virtual pages.
- The range of memory starts at address @var{addr} and is @var{len} bytes
- long. Actually, since you must lock whole pages, it is the range of
- pages that include any part of the specified range.
- When the function returns successfully, each of those pages is backed by
- (connected to) a real frame (is resident) and is marked to stay that
- way. This means the function may cause page-ins and have to wait for
- them.
- When the function fails, it does not affect the lock status of any
- pages.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. @code{errno} values
- specific to this function are:
- @table @code
- @item ENOMEM
- @itemize @bullet
- @item
- At least some of the specified address range does not exist in the
- calling process' virtual address space.
- @item
- The locking would cause the process to exceed its locked page limit.
- @end itemize
- @item EPERM
- The calling process is not superuser.
- @item EINVAL
- @var{len} is not positive.
- @item ENOSYS
- The kernel does not provide @code{mlock} capability.
- @end table
- @end deftypefun
- @deftypefun int mlock2 (const void *@var{addr}, size_t @var{len}, unsigned int @var{flags})
- @standards{Linux, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- This function is similar to @code{mlock}. If @var{flags} is zero, a
- call to @code{mlock2} behaves exactly as the equivalent call to @code{mlock}.
- The @var{flags} argument must be a combination of zero or more of the
- following flags:
- @vtable @code
- @item MLOCK_ONFAULT
- @standards{Linux, sys/mman.h}
- Only those pages in the specified address range which are already in
- memory are locked immediately. Additional pages in the range are
- automatically locked in case of a page fault and allocation of memory.
- @end vtable
- Like @code{mlock}, @code{mlock2} returns zero on success and @code{-1}
- on failure, setting @code{errno} accordingly. Additional @code{errno}
- values defined for @code{mlock2} are:
- @table @code
- @item EINVAL
- The specified (non-zero) @var{flags} argument is not supported by this
- system.
- @end table
- @end deftypefun
- You can lock @emph{all} a process' memory with @code{mlockall}. You
- unlock memory with @code{munlock} or @code{munlockall}.
- To avoid all page faults in a C program, you have to use
- @code{mlockall}, because some of the memory a program uses is hidden
- from the C code, e.g. the stack and automatic variables, and you
- wouldn't know what address to tell @code{mlock}.
- @deftypefun int munlock (const void *@var{addr}, size_t @var{len})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{munlock} unlocks a range of the calling process' virtual pages.
- @code{munlock} is the inverse of @code{mlock} and functions completely
- analogously to @code{mlock}, except that there is no @code{EPERM}
- failure.
- @end deftypefun
- @deftypefun int mlockall (int @var{flags})
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{mlockall} locks all the pages in a process' virtual memory address
- space, and/or any that are added to it in the future. This includes the
- pages of the code, data and stack segment, as well as shared libraries,
- user space kernel data, shared memory, and memory mapped files.
- @var{flags} is a string of single bit flags represented by the following
- macros. They tell @code{mlockall} which of its functions you want. All
- other bits must be zero.
- @vtable @code
- @item MCL_CURRENT
- Lock all pages which currently exist in the calling process' virtual
- address space.
- @item MCL_FUTURE
- Set a mode such that any pages added to the process' virtual address
- space in the future will be locked from birth. This mode does not
- affect future address spaces owned by the same process so exec, which
- replaces a process' address space, wipes out @code{MCL_FUTURE}.
- @xref{Executing a File}.
- @end vtable
- When the function returns successfully, and you specified
- @code{MCL_CURRENT}, all of the process' pages are backed by (connected
- to) real frames (they are resident) and are marked to stay that way.
- This means the function may cause page-ins and have to wait for them.
- When the process is in @code{MCL_FUTURE} mode because it successfully
- executed this function and specified @code{MCL_CURRENT}, any system call
- by the process that requires space be added to its virtual address space
- fails with @code{errno} = @code{ENOMEM} if locking the additional space
- would cause the process to exceed its locked page limit. In the case
- that the address space addition that can't be accommodated is stack
- expansion, the stack expansion fails and the kernel sends a
- @code{SIGSEGV} signal to the process.
- When the function fails, it does not affect the lock status of any pages
- or the future locking mode.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. @code{errno} values
- specific to this function are:
- @table @code
- @item ENOMEM
- @itemize @bullet
- @item
- At least some of the specified address range does not exist in the
- calling process' virtual address space.
- @item
- The locking would cause the process to exceed its locked page limit.
- @end itemize
- @item EPERM
- The calling process is not superuser.
- @item EINVAL
- Undefined bits in @var{flags} are not zero.
- @item ENOSYS
- The kernel does not provide @code{mlockall} capability.
- @end table
- You can lock just specific pages with @code{mlock}. You unlock pages
- with @code{munlockall} and @code{munlock}.
- @end deftypefun
- @deftypefun int munlockall (void)
- @standards{POSIX.1b, sys/mman.h}
- @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
- @code{munlockall} unlocks every page in the calling process' virtual
- address space and turns off @code{MCL_FUTURE} future locking mode.
- The return value is zero if the function succeeds. Otherwise, it is
- @code{-1} and @code{errno} is set accordingly. The only way this
- function can fail is for generic reasons that all functions and system
- calls can fail, so there are no specific @code{errno} values.
- @end deftypefun
- @ignore
- @c This was never actually implemented. -zw
- @node Relocating Allocator
- @section Relocating Allocator
- @cindex relocating memory allocator
- Any system of dynamic memory allocation has overhead: the amount of
- space it uses is more than the amount the program asks for. The
- @dfn{relocating memory allocator} achieves very low overhead by moving
- blocks in memory as necessary, on its own initiative.
- @c @menu
- @c * Relocator Concepts:: How to understand relocating allocation.
- @c * Using Relocator:: Functions for relocating allocation.
- @c @end menu
- @node Relocator Concepts
- @subsection Concepts of Relocating Allocation
- @ifinfo
- The @dfn{relocating memory allocator} achieves very low overhead by
- moving blocks in memory as necessary, on its own initiative.
- @end ifinfo
- When you allocate a block with @code{malloc}, the address of the block
- never changes unless you use @code{realloc} to change its size. Thus,
- you can safely store the address in various places, temporarily or
- permanently, as you like. This is not safe when you use the relocating
- memory allocator, because any and all relocatable blocks can move
- whenever you allocate memory in any fashion. Even calling @code{malloc}
- or @code{realloc} can move the relocatable blocks.
- @cindex handle
- For each relocatable block, you must make a @dfn{handle}---a pointer
- object in memory, designated to store the address of that block. The
- relocating allocator knows where each block's handle is, and updates the
- address stored there whenever it moves the block, so that the handle
- always points to the block. Each time you access the contents of the
- block, you should fetch its address anew from the handle.
- To call any of the relocating allocator functions from a signal handler
- is almost certainly incorrect, because the signal could happen at any
- time and relocate all the blocks. The only way to make this safe is to
- block the signal around any access to the contents of any relocatable
- block---not a convenient mode of operation. @xref{Nonreentrancy}.
- @node Using Relocator
- @subsection Allocating and Freeing Relocatable Blocks
- @pindex malloc.h
- In the descriptions below, @var{handleptr} designates the address of the
- handle. All the functions are declared in @file{malloc.h}; all are GNU
- extensions.
- @comment malloc.h
- @comment GNU
- @c @deftypefun {void *} r_alloc (void **@var{handleptr}, size_t @var{size})
- This function allocates a relocatable block of size @var{size}. It
- stores the block's address in @code{*@var{handleptr}} and returns
- a non-null pointer to indicate success.
- If @code{r_alloc} can't get the space needed, it stores a null pointer
- in @code{*@var{handleptr}}, and returns a null pointer.
- @end deftypefun
- @comment malloc.h
- @comment GNU
- @c @deftypefun void r_alloc_free (void **@var{handleptr})
- This function is the way to free a relocatable block. It frees the
- block that @code{*@var{handleptr}} points to, and stores a null pointer
- in @code{*@var{handleptr}} to show it doesn't point to an allocated
- block any more.
- @end deftypefun
- @comment malloc.h
- @comment GNU
- @c @deftypefun {void *} r_re_alloc (void **@var{handleptr}, size_t @var{size})
- The function @code{r_re_alloc} adjusts the size of the block that
- @code{*@var{handleptr}} points to, making it @var{size} bytes long. It
- stores the address of the resized block in @code{*@var{handleptr}} and
- returns a non-null pointer to indicate success.
- If enough memory is not available, this function returns a null pointer
- and does not modify @code{*@var{handleptr}}.
- @end deftypefun
- @end ignore
- @ignore
- @comment No longer available...
- @comment @node Memory Warnings
- @comment @section Memory Usage Warnings
- @comment @cindex memory usage warnings
- @comment @cindex warnings of memory almost full
- @pindex malloc.c
- You can ask for warnings as the program approaches running out of memory
- space, by calling @code{memory_warnings}. This tells @code{malloc} to
- check memory usage every time it asks for more memory from the operating
- system. This is a GNU extension declared in @file{malloc.h}.
- @comment malloc.h
- @comment GNU
- @comment @deftypefun void memory_warnings (void *@var{start}, void (*@var{warn-func}) (const char *))
- Call this function to request warnings for nearing exhaustion of virtual
- memory.
- The argument @var{start} says where data space begins, in memory. The
- allocator compares this against the last address used and against the
- limit of data space, to determine the fraction of available memory in
- use. If you supply zero for @var{start}, then a default value is used
- which is right in most circumstances.
- For @var{warn-func}, supply a function that @code{malloc} can call to
- warn you. It is called with a string (a warning message) as argument.
- Normally it ought to display the string for the user to read.
- @end deftypefun
- The warnings come when memory becomes 75% full, when it becomes 85%
- full, and when it becomes 95% full. Above 95% you get another warning
- each time memory usage increases.
- @end ignore
|