Aggiunte altre quattro righe sull'allocazione della memoria
[gapil.git] / process.tex
index 52c1f40f95228ebe236d617825bab3b6c86f1222..7260dbb354d5bbb6a55edb9f60900ae9507684fc 100644 (file)
@@ -400,7 +400,6 @@ salvato sul file, in quanto viene inizializzato a zero al caricamento del
 programma.
 
 
-
 \subsection{Allocazione della memoria per i programmi C}
 \label{sec:proc_mem_alloc}
 
@@ -419,15 +418,20 @@ medesima.
 Esiste però un terzo tipo di allocazione, che non è prevista dal linguaggio C,
 che è l'allocazione dinamica della memoria, necessaria quando il quantitativo
 di memoria che serve è determinabile solo in corso di esecuzione del
-programma.
+programma. 
 
 Il C non consente di usare variabili allocate dinamicamente, non è possibile
 cioè definire in fase di programmazione una variabile le cui dimensioni
 possano essere modificate durante l'esecuzione del programma; però le librerie
 del C forniscono una serie opportuna di funzioni per permettere l'allocazione
 dinamica di spazio in memoria (in genere nello heap, usando la system call
-\texttt{sbrk}), solo che a questo punto sarà possibile usarlo solo in maniera
-indiretta attraverso dei puntatori.
+\texttt{sbrk}), solo che a questo punto detto spazio sarà accessibile solo in
+maniera indiretta attraverso dei puntatori.
+
+
+\subsection{Le funzioni \texttt{malloc}, \texttt{calloc}, \texttt{realloc} e
+  \texttt{free}}  
+\label{sec:proc_mem_malloc}
 
 Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
 quattro, i prototipi sono i seguenti:
@@ -462,20 +466,97 @@ quattro, i prototipi sono i seguenti:
 Il puntatore che le funzioni di allocazione ritornano è garantito essere
 sempre correttamente allineato per tutti i tipi di dati; ad esempio sulle
 macchine a 32 bit in genere è allineato a multipli di 4 bytes e sulle macchine
-a 64 bit a multipli di 8 bytes. Il puntatori ritornati sono di tipo generico
-così non è necessario effettuare un cast per assegnarli a puntatori di altro
-tipo.
+a 64 bit a multipli di 8 bytes. 
+
+In genere su usano le funzioni \texttt{malloc} e \texttt{calloc} per allocare
+dinamicamente la memoria necessaria al programma, siccome i puntatori
+ritornati sono di tipo generico non è necessario effettuare un cast per
+assegnarli a puntatori al tipo di variabile per la quale si effettua la
+allocazione.
+
+La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando
+\texttt{free}\footnote{le glibc provvedono anche una funzione \texttt{cfree}
+  defininita per compatibilità con SunOS, che è deprecata} una volta che non
+sia più necessaria. Questa funzione vuole come parametro un puntatore
+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.
+
+La funzione \texttt{realloc} si usa invece per cambiare (in genere aumentare)
+la dimensione di un'area di memoria precedentemente allocata, la funzione
+vuole in ingresso il puntatore restituito dalla precedente chiamata ad una
+\texttt{malloc} (se è passato un valore \texttt{NULL} allora la funzione si
+comporta come \texttt{malloc}\footnote{questo è vero per linux e
+  l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
+  vecchie implementazioni, inoltre alcune versioni delle librerie del C
+  consentivano di usare \texttt{realloc} anche per un puntatore liberato con
+  \texttt{free} purché non ci fossero state altre chiamate a funzioni di
+  allocazione, questa funzionalità è totalmente deprecata e non è consentita
+  sotto linux}), ad esempio quando si deve far crescere la dimensione di un
+vettore; in questo caso se è disponibile dello spazio adiacente al precedente
+la funzione lo utilzza, altrimenti rialloca altrove un blocco della dimensione
+voluta copiandoci automaticamente il contenuto, lo spazio in più non viene
+inizializzato. 
+
+Il fatto che il blocco di memoria restituito da \texttt{realloc} possa
+camabiare comporta che si deve sempre riassegnare al puntatore passato per il
+ridimensionamento il valore di ritorno della funzione, e che non ci devono
+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; 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. 
 
 
+\subsection{La funzione \texttt{alloca}}  
+\label{sec:proc_mem_alloca}
+
+
+
+\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_mlock}
+
+
+\section{Il controllo di flusso non locale}
+\label{sec:proc_flux}
 
 
 \section{La gestione di parametri e opzioni}
-\label{sec:parameter_options}
+\label{sec:proc_options}
 
 Il passaggio dei parametri e delle variabili di ambiente dalla riga di comando
 al singolo programma quando viene lanciato è effettuato attraverso le
@@ -607,7 +688,6 @@ la gestione di queste ultime 
 versione estesa di \texttt{getopt}.
 
 
-
 \subsection{Le variabili di ambiente}
 \label{sec:proc_env_var}