+allocato una quantità sufficientemente ampia di \index{variabili!automatiche}
+variabili automatiche, in modo che esse vengano mappate in RAM dallo
+\itindex{stack} \textit{stack}, dopo di che, per essere sicuri che esse siano
+state effettivamente portate in memoria, ci si scrive sopra.
+
+\itindend{memory~locking}
+
+\index{memoria~virtuale|)}
+
+
+\subsection{Gestione avanzata dell'allocazione della memoria}
+\label{sec:proc_memory_adv_management}
+
+La trattazione delle funzioni di allocazione di sez.~\ref{sec:proc_mem_alloc}
+si è limitata a coprire le esigenze generiche di un programma, in cui non si
+hanno dei requisiti specifici e si lascia il controllo delle modalità di
+allocazione alle funzioni di libreria. Tuttavia esistono una serie di casi in
+cui può essere necessario avere un controllo più dettagliato delle modalità
+con cui la memoria viene allocata; nel qual caso potranno venire in aiuto le
+funzioni trattate in questa sezione.
+
+Le prime funzioni che tratteremo sono quelle che consentono di richiedere di
+allocare un blocco di memoria ``\textsl{allineato}'' ad un multiplo una certa
+dimensione. Questo tipo di esigenza emerge usualmente quando si devono
+allocare dei buffer da utilizzare per eseguire dell'I/O diretto su dispositivi
+a blocchi. In questo caso infatti il trasferimento di dati viene eseguito per
+blocchi di dimensione fissa, ed è richiesto che l'indirizzo di partenza del
+buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In
+tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
+funzione specifica.
+
+Tradizionalmente per rispondere a questa esigenza sono state create due
+funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{malloc.h}
+\fdecl{void *valloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+ memoria.}
+\fdecl{void *memalign(size\_t boundary, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+ di \param{boundary}.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{boundary} non è una potenza di due.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+Le funzioni restituiscono il puntatore al buffer di memoria allocata di
+dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo
+di \param{boundary} mentre per \func{valloc} un multiplo della dimensione di
+una pagina di memoria. Nel caso della versione fornita dalla \acr{glibc} la
+memoria allocata con queste funzioni deve essere liberata con \func{free},
+cosa che non è detto accada con altre implementazioni.
+
+Nessuna delle due funzioni ha una chiara standardizzazione e nessuna delle due
+compare in POSIX.1, inoltre ci sono indicazioni discordi sui file che ne
+contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
+ \headfile{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4}
+ e \acr{libc5} la dichiarano in \headfile{malloc.h}, lo stesso vale per
+ \func{memalign} che in alcuni sistemi è dichiarata in \headfile{stdlib.h}.}
+per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
+nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{posix\_memalign(void **memptr, size\_t alignment, size\_t size)}
+\fdesc{Alloca un buffer di memoria allineato ad un multiplo
+ di \param{alignment}.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{alignment} non è potenza di due e multiplo
+ di \code{sizeof(void *)}.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+La funzione restituisce il puntatore al buffer allocato di dimensioni pari
+a \param{size} nella variabile (di tipo \texttt{void *}) posta all'indirizzo
+indicato da \param{memptr}. La funzione fallisce nelle stesse condizioni delle
+due funzioni precedenti, ma a loro differenza restituisce direttamente come
+valore di ritorno il codice di errore. Come per le precedenti la memoria
+allocata con \func{posix\_memalign} deve essere disallocata con \func{free},
+che in questo caso però è quanto richiesto dallo standard. Si tenga presente
+infine che nessuna di queste funzioni inizializza il buffer di memoria
+allocato, il loro comportamento cioè è analogo, allineamento a parte, a quello
+di \func{malloc}.
+
+Un secondo caso in cui risulta estremamente utile poter avere un maggior
+controllo delle modalità di allocazione della memoria è quello in cui cercano
+errori di programmazione. Esempi di questi errori sono i \itindex{double~free}
+\textit{double free}, o i cosiddetti \itindex{buffer~overrun} \textit{buffer
+ overrun}, cioè le scritture su un buffer oltre le dimensioni della sua
+allocazione,\footnote{entrambe queste operazioni causano in genere la
+ corruzione dei dati di controllo delle funzioni di allocazione, che vengono
+ anch'essi mantenuti nello \itindex{heap} \textit{heap} per tenere traccia
+ delle zone di memoria allocata.} o i classici \itindex{memory~leak}
+\textit{memory leak}.
+
+Abbiamo visto in sez.~\ref{sec:proc_mem_lock} come una prima funzionalità di
+ausilio nella ricerca di questi errori sia l'uso della variabile di ambiente
+\envvar{MALLOC\_CHECK\_}. Una modalità alternativa per effettuare dei
+controlli di consistenza sullo stato delle allocazioni di memoria eseguite con
+\func{malloc}, anche questa fornita come estensione specifica (e non standard)
+della \acr{glibc}, è quella di utilizzare la funzione \funcd{mcheck}, che deve
+essere chiamata prima di eseguire qualunque allocazione con \func{malloc}; il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{mcheck.h}
+\fdecl{int mcheck(void (*abortfn) (enum mcheck\_status status))}
+\fdesc{Attiva i controlli di consistenza delle allocazioni di memoria.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errorre;
+ \var{errno} non viene impostata.}
+\end{funcproto}
+
+La funzione consente di registrare una funzione di emergenza che verrà
+eseguita tutte le volte che, in una successiva esecuzione di \func{malloc},
+venissero trovate delle inconsistenze, come delle operazioni di scrittura
+oltre i limiti dei buffer allocati. Per questo motivo la funzione deve essere
+chiamata prima di qualunque allocazione di memoria, altrimenti fallirà.
+
+Se come primo argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata
+una funzione predefinita che stampa un messaggio di errore ed invoca la
+funzione \func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si
+dovrà creare una funzione personalizzata in grado di ricevere il tipo di
+errore ed agire di conseguenza.
+
+Nonostante la scarsa leggibilità del prototipo si tratta semplicemente di
+definire una funzione di tipo \code{void abortfn(enum mcheck\_status status)},
+che non deve restituire nulla e che deve avere un unico argomento di tipo
+\code{mcheck\_status}. In caso di errore la funzione verrà eseguita ricevendo
+un opportuno valore di \param{status} che è un tipo enumerato che può assumere
+soltanto i valori di tab.~\ref{tab:mcheck_status_value} che indicano la
+tipologia di errore riscontrata.