Finita alloca, iniziato brk e sbrk.
[gapil.git] / process.tex
index 7260dbb354d5bbb6a55edb9f60900ae9507684fc..c3a801c623fac9ed041d83225c8a023b82824082 100644 (file)
@@ -528,20 +528,82 @@ viene opportunamente liberata (quello che in inglese viene chiamato
 \textit{memory-leak}, traducibile come \textsl{perdita di memoria}).
 
 Un caso tipico è quando l'allocazione viene fatta da una subroutine per un uso
-locale, ma la memoria non viene liberata una volta usata; in questo caso la
-memoria resta allocata, causando a lungo andare un esaurimento della memoria
-disponibile con un conseguente crash dell'applicazione in un momento del tutto
-scorrelato rispetto al verificarsi della condizione di errore. 
-
+locale, ma la memoria non viene liberata una volta usata; chiamate ripetute
+alla stessa suubroutine causeranno a lungo andare un esaurimento della memoria
+disponibile, con un conseguente crash dell'applicazione che può avvenire in
+qualunque momento senza nessuna relazione con la subroutine che contiene
+l'errore. 
+
+Per questo motivo l'implementazione delle routine di allocazione delle glibc
+mette a disposizione una serie di funzionalità (su cui torneremo in
+\secref{sec:proc_mem_advanced}) che permettono di tracciare le allocazioni e
+le disallocazione, e definisce anche una serie di possibili agganci che
+permettono di sostituire alle funzioni di libreria una propria versione (che
+può essere più o meno specializzata per il debugging).
 
 \subsection{La funzione \texttt{alloca}}  
 \label{sec:proc_mem_alloca}
 
+Una alternativa possibile all'uso di \texttt{malloc}, che non soffre del tipo
+di problemi di memomry leak descritti in precedenza è la funzione
+\texttt{alloca} che invece che allocare la memoria nello heap usa lo il
+segmento di stack della funzione corrente. La sintassi è identica:
+\begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
+  Alloca \texttt{size} bytes 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 \texttt{NULL} in caso di fallimento, nel qual caso
+  \texttt{errno} viene settata a \texttt{ENOMEM}.
+\end{prototype}
+ma in questo caso non è più necessario liberare la memoria in quanto questa
+viene rilasciata automaticamente al ritorno della funzione.
+
+Come è evidente questa funzione ha molti vantaggi, e permette di evitare i
+problemi di memory leak non essendo più necessaria la deallocazione esplicita;
+una delle ragioni principali per usarla è però che funziona anche quando si
+usa \texttt{longjump} per uscire con un salto non locale da una funzione (vedi
+\secref{sec:proc_longjmp}), 
+
+Un altro vantaggio e che in Linux la funzione è molto veloce e non viene
+sprecato spazio, infatti non è necessario gestire un pool di memoria da
+riservare e si evitano anche problemi di frammentazione.
+
+Gli svantaggi sono che la funzione non è disponibile su tutti gli unix quando
+non è possibile aumentare le dimensioni dello stack una volta chiamata una
+funzione e quindi l'uso limita la portabilità dei programmi, inoltre se si
+cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un
+segnale di \textit{segmentation violation} analogo a quello che si avrebbe da
+una ricorsione infinita.
 
 
 \subsection{Le funzioni \texttt{brk} e \texttt{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 (ad esempio per implementare
+una propria versione di \texttt{malloc}. Le  funzione sono:
+\begin{prototype}{unistd.h}{int *brk(void end_data_segment)}
+  Sposta la fine del segmento dei dati all'indirizzo specificato da
+  \texttt{end_data_segment}.
+  
+  La funzione restituisce 0 in caso di successo e -1 in caso di fallimento,
+  nel qual caso \texttt{errno} viene settata a \texttt{ENOMEM}.
+\end{prototype}
+\begin{prototype}{unistd.h}{int *sbrk(ptrdiff\_t increment)}
+  Incrementa lo spazio dati di un programma di \texttt{increment}. 
+  
+  La funzione restituisce il puntatore all'inzio della nuova zona di memoria
+  allocata in caso di successo e \texttt{NULL} in caso di fallimento, nel qual
+  caso \texttt{errno} viene settata a \texttt{ENOMEM}.
+\end{prototype}
+
+Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e
+per i programmi normali è opportuno usare le funzioni di allocazione standard
+descritte in precedenza, che sono costruite su di esse.  In genere si usa
+\texttt{sbrk} con un valore zero per ottenere l'attuale posizione della fine
+del segmento dati. 
+
 
 \subsection{La personalizzazione delle funzioni di allocazione} 
 \label{sec:proc_mem_malloc_custom}
@@ -552,7 +614,7 @@ scorrelato rispetto al verificarsi della condizione di errore.
 
 
 \section{Il controllo di flusso non locale}
-\label{sec:proc_flux}
+\label{sec:proc_longjmp}
 
 
 \section{La gestione di parametri e opzioni}