X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=process.tex;h=52da830dcb9928b492b66bb79d68fff7a4baca9c;hb=bf451665e088e4e88ac18f7f81ff7850be8734cc;hp=23206304b18e5554b471042a77943c67ecafa198;hpb=b4611e5ee9458ce9b06b2cd35b661331b687ba78;p=gapil.git diff --git a/process.tex b/process.tex index 2320630..52da830 100644 --- a/process.tex +++ b/process.tex @@ -481,11 +481,6 @@ sia pi restituito da una precedente chiamata a una qualunque delle funzioni di allocazione e che non sia già stato liberato da un'altra chiamata a \texttt{free}, in caso contrario il comportamento della funzione è indefinito. -Uno degli errori più comuni (specie se si ha a che fare con array di -puntatori) è infatti quello di chiamare \texttt{free} due volte; per evitare -questo problema una soluzione è quella di assegnare sempre a \texttt{NULL} -ogni puntatore liberato con \texttt{free}, dato che, quando il parametro è un -puntatore nullo, non viene non viene effettuata nessuna operazione. La funzione \texttt{realloc} si usa invece per cambiare (in genere aumentare) la dimensione di un'area di memoria precedentemente allocata, la funzione @@ -510,24 +505,80 @@ essere altri puntatori che puntino all'interno di un'area che si vuole ridimensionare. +Uno degli errori più comuni (specie se si ha a che fare con array di +puntatori) è infatti quello di chiamare \texttt{free} più di una volta sullo +stesso puntatore; per evitare questo problema una soluzione di ripiego è +quella di assegnare sempre a \texttt{NULL} ogni puntatore liberato con +\texttt{free}, dato che, quando il parametro è un puntatore nullo, +\texttt{free} non esegue nessuna operazione. + +Linux e le glibc hanno una implementazione delle routine di allocazione che è +controllabile dall'utente attraverso alcune variabili di ambiente, in +particolare diventa possibile tracciare questo tipo di errori usando la +variabile \texttt{MALLOC\_CHECK\_} che quando viene settata mette in uso una +versione meno efficiente delle funzioni, che però è più tollerante nei +confronti di piccoli errori come quello di chiamate doppie a \texttt{free}; in +pparticolare se la variabile è posta a zero gli errori vengono ignorati, se è +posta ad 1 viene stampato un avviso sullo standard error e se + + +Il problema più comune e più difficile da tracciare che si incontra con +l'allocazione della memoria è però quando la memoria non più utilizzata non +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; 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). - altrimenti si quello che -viene definito una \textsl{perdita di memoria} (in inglese -\textit{memory-leak}) +\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. -\subsection{La funzione \texttt{alloca}} -\label{sec:proc_mem_alloca} +Come è evidente questa funzione ha molti vantaggi, in particolare il fatto che +la memoria venga rilasciata automaticamente +in particolare in Linux +la funzione è molto veloce e non viene sprecato spazio, non dovendo gestire un +pool di zone di memoria da riservare; si evita così anche la frammentazione. +Gli svantaggi sono che quando \subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} \label{sec:proc_mem_sbrk} +\subsection{La personalizzazione delle funzioni di allocazione} +\label{sec:proc_mem_malloc_custom} + + \subsection{Il controllo della memoria virtuale} -\label{sec:proc_mem_sbrk} +\label{sec:proc_mem_mlock} + \section{Il controllo di flusso non locale} \label{sec:proc_flux}