X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=23206304b18e5554b471042a77943c67ecafa198;hp=52c1f40f95228ebe236d617825bab3b6c86f1222;hb=b4611e5ee9458ce9b06b2cd35b661331b687ba78;hpb=66765a9be9a61085dd00abd92d99a24b23dc844b diff --git a/process.tex b/process.tex index 52c1f40..2320630 100644 --- a/process.tex +++ b/process.tex @@ -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,75 @@ 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. +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 +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. + 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} + + + +\subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} +\label{sec:proc_mem_sbrk} + + +\subsection{Il controllo della memoria virtuale} +\label{sec:proc_mem_sbrk} + +\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 +666,6 @@ la gestione di queste ultime versione estesa di \texttt{getopt}. - \subsection{Le variabili di ambiente} \label{sec:proc_env_var}