-Il problema più comune e più difficile da risolvere che si incontra con le
-routine di allocazione è quando non viene opportunamente liberata la memoria
-non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak},
-(cioè \textsl{perdita di memoria}).
-
-Un caso tipico che illustra il problema è quello in cui in una subroutine si
-alloca della memoria per uso locale senza liberarla prima di uscire. La
-memoria resta così allocata fino alla terminazione del processo. Chiamate
-ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni,
-causando a lungo andare un esaurimento della memoria disponibile (e la
-probabile l'impossibilità di proseguire l'esecuzione programma).
-
-Il problema è che l'esaurimento della memoria può avvenire in qualunque
-momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
-essere in una sezione del codice che non ha alcuna relazione con la subroutine
-che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
-\textit{memory leak}.
-
-Per ovviare a questi problemi l'implementazione delle routine di allocazione
-delle \acr{glibc} mette a disposizione una serie di funzionalità (su cui
-torneremo in \secref{sec:xxx_advanced}) che permettono di tracciare le
-allocazioni e le disallocazione, e definisce anche una serie di possibili
-\textit{hook} (\textsl{ganci}) che permettono di sostituire alle funzioni di
-libreria una propria versione (che può essere più o meno specializzata per il
-debugging).
-
-
-\subsection{La funzione \func{alloca}}
-\label{sec:proc_mem_alloca}
-
-Una possibile alternativa all'uso di \func{malloc}, che non soffre dei
-problemi di memory leak descritti in precedenza, è la funzione \func{alloca},
-che invece di allocare la memoria nello heap usa il segmento di stack della
-funzione corrente. La sintassi è identica a quella di \func{malloc}, il suo
-prototipo è:
-\begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
- Alloca \var{size} byte nel segmento di stack della funzione chiamante.
- La memoria non viene inizializzata.
-
- La funzione restituisce il puntatore alla zona di memoria allocata in caso
- di successo e \macro{NULL} in caso di fallimento, nel qual caso
- \var{errno} viene settata a \macro{ENOMEM}.
-\end{prototype}
-\noindent ma in questo caso non è più necessario liberare la memoria (e quindi
-non esiste un analogo della \func{free}) in quanto essa viene rilasciata
-automaticamente al ritorno della funzione.
-
-Come è evidente questa funzione ha molti vantaggi, anzitutto permette di
-evitare alla radice i problemi di memory leak, dato che non serve più la
-deallocazione esplicita; inoltre la deallocazione automatica funziona anche
-quando si usa \func{longjmp} per uscire da una subroutine con un salto non
-locale da una funzione (vedi \secref{sec:proc_longjmp}).
-
-Un altro vantaggio è che in Linux la funzione è molto più veloce di
-\func{malloc} e non viene sprecato spazio, infatti non è necessario gestire un
-pool di memoria da riservare e si evitano così anche i problemi di
-frammentazione di quest'ultimo, che comportano inefficienze sia
-nell'allocazione della memoria che nell'esecuzione dell'allocazione.
-
-Gli svantaggi sono che questa funzione non è disponibile su tutti gli Unix, e
-non è inserita né nello standard POSIX né in SUSv3 (ma è presente in BSD), il
-suo utilizzo quindi limita la portabilità dei programmi. Inoltre la funzione
-non può essere usata nella lista degli argomenti di una funzione, perché lo
-spazio verrebbe allocato nel mezzo degli stessi.
-
-% Questo è riportato solo dal manuale delle glibc, nelle man page non c'è
-% traccia di tutto ciò
-%
-%Inoltre se si
-%cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un
-%segnale di \textit{segment violation} analogo a quello che si avrebbe da una
-%ricorsione infinita.
-
-Inoltre non è chiaramente possibile usare \func{alloca} per allocare memoria
-che deve poi essere usata anche al di fuori della funzione in cui essa viene
-chiamata, dato che all'uscita dalla funzione lo spazio allocato diventerebbe
-libero, e potrebbe essere sovrascritto all'invocazione di nuove funzioni.
-Questo è lo stesso problema che si può avere con le variabili automatiche, su
-cui torneremo in \secref{sec:proc_auto_var}.
-
-
-\subsection{Le funzioni \func{brk} e \func{sbrk}}
-\label{sec:proc_mem_sbrk}
-
-L'uso di queste funzioni è necessario solo quando si voglia accedere alle
-analoghe system call a cui fanno da interfaccia. I loro prototipi sono:
-\begin{functions}
- \headdecl{unistd.h}
- \funcdecl{int brk(void *end\_data\_segment)}
- Sposta la fine del segmento dei dati all'indirizzo specificato da
- \var{end\_data\_segment}.
-
- La funzione restituisce 0 in caso di successo e -1 in caso di
- fallimento, nel qual caso \var{errno} viene settata a \macro{ENOMEM}.
-
- \funcdecl{void *sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un
- programma di \var{increment}. Un valore zero restituisce l'attuale posizione
- della fine del segmento dati.
-
- La funzione restituisce il puntatore all'inizio della nuova zona di memoria
- allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual
- caso \macro{errno} viene settata a \macro{ENOMEM}.
-\end{functions}
-\noindent in genere si usa \func{sbrk} con un valore zero per ottenere
-l'attuale posizione della fine del segmento dati.
-
-Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e
-per i programmi normali è sempre opportuno usare le funzioni di allocazione
-standard descritte in precedenza, che sono costruite su di esse. L'uso di
-queste funzione è ristretto alle specifiche necessità di chi debba
-implementare una sua versione delle routine di allocazione.
-
-
-% \subsection{La personalizzazione delle funzioni di allocazione}
-% \label{sec:proc_mem_malloc_custom}
+\itindbeg{memory~leak}
+
+L'errore di programmazione più comune e più difficile da risolvere che si
+incontra con le funzioni di allocazione è quando non viene opportunamente
+liberata la memoria non più utilizzata, quello che in inglese viene chiamato
+\textit{memory leak}, cioè una \textsl{perdita di memoria}.
+
+Un caso tipico che illustra il problema è quello in cui in una propria
+funzione si alloca della memoria per uso locale senza liberarla prima di
+uscire. La memoria resta così allocata fino alla terminazione del processo.
+Chiamate ripetute alla stessa funzione continueranno ad effettuare altre
+allocazioni, che si accumuleranno causando a lungo andare un esaurimento della
+memoria disponibile e la probabile impossibilità di proseguire l'esecuzione
+del programma.
+
+Il problema è che l'esaurimento della memoria può avvenire in qualunque
+momento, in corrispondenza ad una qualunque chiamata di \func{malloc} che può
+essere in una sezione del codice che non ha alcuna relazione con la funzione
+che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
+\textit{memory leak}. In C e C++ il problema è particolarmente sentito. In
+C++, per mezzo della programmazione ad oggetti, il problema dei \textit{memory
+ leak} si può notevolmente ridimensionare attraverso l'uso accurato di
+appositi oggetti come gli \textit{smartpointers}. Questo però in genere va a
+scapito delle prestazioni dell'applicazione in esecuzione.
+
+% TODO decidere cosa fare di questo che segue In altri linguaggi come il java
+% e recentemente il C\# il problema non si pone nemmeno perché la gestione
+% della memoria viene fatta totalmente in maniera automatica, ovvero il
+% programmatore non deve minimamente preoccuparsi di liberare la memoria
+% allocata precedentemente quando non serve più, poiché l'infrastruttura del
+% linguaggio gestisce automaticamente la cosiddetta
+% \itindex{garbage~collection} \textit{garbage collection}. In tal caso,
+% attraverso meccanismi simili a quelli del \textit{reference counting},
+% quando una zona di memoria precedentemente allocata non è più riferita da
+% nessuna parte del codice in esecuzione, può essere deallocata
+% automaticamente in qualunque momento dall'infrastruttura.
+
+% Anche questo va a scapito delle prestazioni dell'applicazione in esecuzione
+% (inoltre le applicazioni sviluppate con tali linguaggi di solito non sono
+% eseguibili compilati, come avviene invece per il C ed il C++, ed è necessaria
+% la presenza di una infrastruttura per la loro interpretazione e pertanto hanno
+% di per sé delle prestazioni più scadenti rispetto alle stesse applicazioni
+% compilate direttamente). Questo comporta però il problema della non
+% predicibilità del momento in cui viene deallocata la memoria precedentemente
+% allocata da un oggetto.
+
+Per limitare l'impatto di questi problemi, e semplificare la ricerca di
+eventuali errori, l'implementazione delle funzioni di allocazione nella
+\acr{glibc} mette a disposizione una serie di funzionalità che permettono di
+tracciare le allocazioni e le disallocazioni, e definisce anche una serie di
+possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
+funzioni di libreria una propria versione (che può essere più o meno
+specializzata per il debugging). Esistono varie librerie che forniscono dei
+sostituti opportuni delle funzioni di allocazione in grado, senza neanche
+ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
+ \url{http://dmalloc.com/} di Gray Watson ed \textit{Electric Fence} di Bruce
+ Perens.} di eseguire diagnostiche anche molto complesse riguardo
+l'allocazione della memoria. Vedremo alcune delle funzionalità di ausilio
+presenti nella \acr{glibc} in sez.~\ref{sec:proc_memory_adv_management}.
+
+\itindend{memory~leak}
+
+Una possibile alternativa all'uso di \func{malloc}, per evitare di soffrire
+dei problemi di \textit{memory leak} descritti in precedenza, è di allocare la
+memoria nel segmento di \textit{stack} della funzione corrente invece che
+nello \textit{heap}. Per farlo si può usare la funzione \funcd{alloca}, la cui
+sintassi è identica a quella di \func{malloc}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{void *alloca(size\_t size)}
+\fdesc{Alloca un'area di memoria nello \textit{stack}.}
+}
+{La funzione ritorna il puntatore alla zona di memoria allocata, in caso
+ di errore il comportamento è indefinito.}
+\end{funcproto}
+
+La funzione alloca la quantità di memoria (non inizializzata) richiesta
+dall'argomento \param{size} nel segmento di \textit{stack} della funzione
+chiamante. Con questa funzione non è più necessario liberare la memoria
+allocata, e quindi non esiste un analogo della \func{free}, in quanto essa
+viene rilasciata automaticamente al ritorno della funzione.
+
+Come è evidente questa funzione ha alcuni vantaggi interessanti, anzitutto
+permette di evitare alla radice i problemi di \textit{memory leak}, dato che
+non serve più la deallocazione esplicita; inoltre la deallocazione automatica
+funziona anche quando si usa \func{longjmp} per uscire da una subroutine con
+un salto non locale da una funzione (vedi sez.~\ref{sec:proc_longjmp}). Un
+altro vantaggio è che in Linux la funzione è molto più veloce di \func{malloc}
+e non viene sprecato spazio, infatti non è necessario gestire un pool di
+memoria da riservare e si evitano così anche i problemi di frammentazione di
+quest'ultimo, che comportano inefficienze sia nell'allocazione della memoria
+che nell'esecuzione dell'allocazione.
+
+Gli svantaggi sono che questa funzione non è disponibile su tutti gli Unix, e
+non è inserita né nello standard POSIX né in SUSv3 (ma è presente in BSD), il
+suo utilizzo quindi limita la portabilità dei programmi. Inoltre la funzione
+non può essere usata nella lista degli argomenti di una funzione, perché lo
+spazio verrebbe allocato nel mezzo degli stessi. Inoltre non è chiaramente
+possibile usare \func{alloca} per allocare memoria che deve poi essere usata
+anche al di fuori della funzione in cui essa viene chiamata, dato che
+all'uscita dalla funzione lo spazio allocato diventerebbe libero, e potrebbe
+essere sovrascritto all'invocazione di nuove funzioni. Questo è lo stesso
+problema che si può avere con le variabili automatiche, su cui torneremo in
+sez.~\ref{sec:proc_var_passing}.
+
+Infine non esiste un modo di sapere se l'allocazione ha avuto successo, la
+funzione infatti viene realizzata inserendo del codice \textit{inline} nel
+programma\footnote{questo comporta anche il fatto che non è possibile
+ sostituirla con una propria versione o modificarne il comportamento
+ collegando il proprio programma con un'altra libreria.} che si limita a
+modificare il puntatore nello \textit{stack} e non c'è modo di sapere se se ne
+sono superate le dimensioni, per cui in caso di fallimento nell'allocazione il
+comportamento del programma può risultare indefinito, dando luogo ad una
+\textit{segment violation} la prima volta che cercherà di accedere alla
+memoria non effettivamente disponibile.
+
+\index{segmento!dati|(}
+\itindbeg{heap}
+
+Le due funzioni seguenti vengono utilizzate soltanto quando è necessario
+effettuare direttamente la gestione della memoria associata allo spazio dati
+di un processo,\footnote{le due funzioni sono state definite con BSD 4.3, sono
+ marcate obsolete in SUSv2 e non fanno parte delle librerie standard del C e
+ mentre sono state esplicitamente rimosse dallo standard POSIX.1-2001.} per
+poterle utilizzare è necessario definire una della macro di funzionalità (vedi
+sez.~\ref{sec:intro_gcc_glibc_std}) fra \macro{\_BSD\_SOURCE},
+\macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un valore maggiore o
+uguale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int brk(void *addr)}
+\fdesc{Sposta la fine del segmento dati del processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+La funzione è un'interfaccia all'omonima \textit{system call} ed imposta
+l'indirizzo finale del segmento dati di un processo (più precisamente dello
+\textit{heap}) all'indirizzo specificato da \param{addr}. Quest'ultimo deve
+essere un valore ragionevole e la dimensione totale non deve comunque eccedere
+un eventuale limite (vedi sez.~\ref{sec:sys_resource_limit}) sulle dimensioni
+massime del segmento dati del processo.
+
+Il valore di ritorno della funzione fa riferimento alla versione fornita dalla
+\acr{glibc}, in realtà in Linux la \textit{system call} corrispondente
+restituisce come valore di ritorno il nuovo valore della fine del segmento
+dati in caso di successo e quello corrente in caso di fallimento, è la
+funzione di interfaccia usata dalla \acr{glibc} che fornisce i valori di
+ritorno appena descritti; se si usano librerie diverse questo potrebbe non
+accadere.
+
+Una seconda funzione per la manipolazione diretta delle dimensioni del
+segmento dati\footnote{in questo caso si tratta soltanto di una funzione di
+ libreria, anche se basata sulla stessa \textit{system call}.} è
+\funcd{sbrk}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{void *sbrk(intptr\_t increment)}
+\fdesc{Incrementa la dimensione del segmento dati del processo.}
+}
+{La funzione ritorna il puntatore all'inizio della nuova zona di memoria
+ allocata in caso di successo e \val{NULL} per un errore, nel qual
+ caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+La funzione incrementa la dimensione dello \textit{heap} di un programma del
+valore indicato dall'argomento \param{increment}, restituendo il nuovo
+indirizzo finale dello stesso. L'argomento è definito come di tipo
+\typed{intptr\_t}, ma a seconda della versione delle librerie e del sistema
+può essere indicato con una serie di tipi equivalenti come \type{ptrdiff\_t},
+\type{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzione
+permette di ottenere l'attuale posizione della fine del segmento dati.
+
+Queste due funzioni sono state deliberatamente escluse dallo standard POSIX.1
+dato che per i normali programmi è sempre opportuno usare le funzioni di
+allocazione standard descritte in precedenza, a meno di non voler realizzare
+per proprio conto un diverso meccanismo di gestione della memoria del segmento
+dati.
+\itindend{heap}
+\index{segmento!dati|)}