Cosa sarebbe realloc fare se non c'è spazio sequenziale della memoria?
-
02-10-2019 - |
Domanda
realloc
viene utilizzato per riallocare la memoria in modo dinamico.
Supponiamo che abbia assegnato 7 byte utilizzando la funzione malloc
e ora voglio estenderlo a 30 byte.
Che cosa accadrà in background se non c'è sequenziale (continuamente in una singola riga) spazio di 30 byte nella memoria?
È disponibile uno spazio errori o saranno assegnate in parti?
Soluzione
realloc
lavora dietro le quinte o meno in questo modo:
- Se non v'è sufficiente spazio libero dietro il blocco corrente per soddisfare la richiesta, estendere il blocco corrente e restituisce un puntatore all'inizio del blocco.
- Al contrario, se c'è un grande blocco libero abbastanza altrove, quindi allocare quel blocco, copiare i dati dal vecchio blocco sopra, liberare il vecchio blocco e restituisce un puntatore all'inizio del nuovo blocco
- Else mancato rapporto con il ritorno
NULL
.
Quindi, è possibile verificare per il mancato testando per NULL
, ma essere consapevoli che non sovrascrivere il vecchio puntatore troppo presto:
int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
int* temp = realloc(p, y);
if (NULL == temp)
{
/* Handle error; p is still valid */
}
else
{
/* p now possibly points to deallocated memory. Overwrite it with the pointer
to the new block, to start using that */
p = temp;
}
}
Altri suggerimenti
realloc
avrà successo solo se si può restituire un contigua ( "sequenziale" nelle tue parole) blocco di memoria. In assenza di tale blocco esiste, ritornerà NULL
.
realloc () restituisce un puntatore al appena allocata memoria, che è opportunamente allineata per qualsiasi tipo di variabile e può essere diverso da PTR, o NULL se la richiesta non riesce.
Quindi, in altre parole, per rilevare il fallimento, basta controllare se il risultato è nullo.
EDIT:. Come evidenziato nel commento, se la chiamata non riesce, la memoria originale non viene liberato
In generale, dipende dall'implementazione. Su x 86 (-64) di Linux, credo che lo standard Doug Lea malloc algoritmo sarà sempre allocare un minimo di una pagina standard x86 (4096 byte), in modo per lo scenario che hai descritto sopra, sarebbe solo ripristinare i confini per accogliere i byte in più. Quando si tratta di, per esempio, la riassegnazione di un buffer di 7bytes al PAGE_SIZE + 1 Credo che proverà a destinare alla successiva pagina contigui, se disponibile.
Da leggere quanto segue, se si sta sviluppando su Linux:
Per impostazione predefinita, Linux segue una strategia di allocazione della memoria ottimista. Ciò significa che quando malloc () restituisce non-NULL non v'è alcuna garanzia che la memoria è realmente disponibile. Questo è davvero un Bad bug. Nel caso in cui si scopre che il sistema è fuori della memoria, uno o più processi saranno uccisi dal OOM assassino infame. Nel caso in cui Linux è impiegato in circostanze in cui sarebbe meno desiderabile perdere improvvisamente alcuni processi selezionati a caso, ed inoltre la versione del kernel è sufficientemente recente, si può disattivare questo comportamento overcommitting usando un comando come:
# echo 2 > /proc/sys/vm/overcommit_memory
Si veda anche la directory kernel documentazione, file vm / overcommit-contabile e sysctl / vm.txt.
FreeBSD e Mac OS X hanno la funzione reallocf () che libererà il puntatore passato quando la memoria richiesta non può essere allocata (vedi uomo realloc).