Ho trovato che alcune persone e riferimenti come libri affermano che se le origini p != NULL
e p
dall'assegnazione precedente (ad esempio da malloc
), quindi realloc(p, 0)
è equivalente a free(p)
su GNU/Linux. Per supportare questa tesi man realloc
stati esattamente in quel modo (sottolineatura mia andando avanti):Realloc (p, 0) implica veramente free (p) in glibc?
La funzione realloc() modifica la dimensione del blocco di memoria puntato ptr a size byte. Il contenuto sarà invariato nell'intervallo da all'inizio della regione fino al minimo delle vecchie e nuove dimensioni. Se la nuova dimensione è più grande della vecchia dimensione, la memoria aggiunta non sarà inizializzata. Se ptr è NULL, la chiamata è equivalente a malloc (dimensione), per tutti i valori di dimensione; se la dimensione è uguale a zero e ptr non è NULL, quindi la chiamata è equivalente a free (ptr). A meno che ptr sia NULL, deve essere stato restituito da una chiamata precedente a malloc(), calloc() o realloc(). Se l'area puntata a è stata spostata, viene eseguito uno libero (ptr).
come si possono trovare nel this question, il C standard non definisce con precisione ciò che dovrebbe accadere e il comportamento effettivo è definito dall'implementazione. Più in particolare:
Il C11 §7.22.3/P1 funzioni di gestione della memoria dice:
Se la dimensione dello spazio richiesto è pari a zero, il comportamento è implementazione definita: sia un null il puntatore viene restituito o il comportamento è come se la dimensione fosse un valore diverso da zero, con la differenza che il puntatore restituito non deve essere utilizzato per accedere a un oggetto.
e C11 §7.22.3.5 La funzione realloc contiene:
3) (...) Se la memoria per il nuovo oggetto non può essere allocato, il vecchio oggetto è non deallocato e il suo valore non è stato modificato.
4) La funzione
realloc
restituisce un puntatore al nuovo oggetto (che può avere lo stesso valore di un puntatore al vecchio oggetto), o un puntatore nullo se il nuovo oggetto non può essere allocata.
ho scritto qualche codice di base per scoprire il comportamento effettivo con l'aiuto di mcheck
, di controllo della memoria, che è fornito con glibc
:
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a = 5;
int *p, *q;
mtrace();
p = malloc(sizeof(int));
q = &a;
printf("%p\n", (void *) p);
printf("%p\n", (void *) q);
q = realloc(p, 0);
printf("%p\n", (void *) p);
printf("%p\n", (void *) q);
return 0;
}
ed i risultati sono:
$ gcc -g check.c
$ export MALLOC_TRACE=report
$ ./a.out
0xfd3460
0x7ffffbc955cc
0xfd3460
(nil)
[[email protected] workspace]$ mtrace a.out report
Memory not freed:
-----------------
Address Size Caller
0x0000000000fd3460 0x4 at /home/grzegorz/workspace/check.c:12
Come si potrebbe vedere q
impostato su NULL
. Sembra che lo free()
non sia stato davvero chiamato. In realtà non può essere se non la mia interpretazione è corretta: dal realloc
è tornato NULL
puntatore, il nuovo oggetto non avrebbe potuto essere assegnato, il che implica che:
il vecchio oggetto non viene deallocato e il suo valore è invariato
È corretto?
La dicitura relativa a 'realloc (ptr, 0)' equivalente a 'free (ptr)' era in POSIX, ma il [riferimento POSIX reale »(http: //pubs.opengroup. org/onlinepubs/9699919799/functions/realloc.html) ora utilizza la lingua dallo standard C. Lo standard POSIX tuttavia dice "se' realloc() 'restituisce un puntatore nullo, lo spazio puntato da p non è stato liberato". –