Teóricamente puedo decir que
free(ptr);
free(ptr);
es una corrupción de la memoria ya que estamos liberando la memoria que ya se ha liberado.
Pero que si
free(ptr);
ptr=NULL;
free(ptr);
Como el sistema operativo se comportará de una manera indefinida, no puedo obtener un análisis teórico real de lo que está sucediendo. Lo que sea que esté haciendo, ¿es esto una corrupción de memoria o no?
¿Es válido liberar un puntero NULL?
delete NULL
no es válido en C ++. delete se puede aplicar a valores de puntero nulo de tipo concreto, pero no aNULL
.delete (int*) NULL
es legal, pero nodelete NULL
.ptr
apunta a la memoria y no la llamafree
, la memoria se perderá. Configurarlo enNULL
simplemente pierde el control de la memoria y se filtra. Siptr
resulta serNULL
, llamarfree
es una no operación.free(ptr)
conptr = NULL
. Nadie dijo nada de eso.Respuestas:
Consulte ISO-IEC 9899 .
Dicho esto, al mirar diferentes bases de código en la naturaleza, notará que las personas a veces lo hacen:
Esto se debe a que algunos tiempos de ejecución de C (seguro que recuerdo que fue el caso en PalmOS) se bloquean al liberar un
NULL
puntero.Pero hoy en día, creo que es seguro asumir que
free(NULL)
es un nop según las instrucciones del estándar.fuente
free(ptr)
dondeptr
es nulo no tiene efectos secundarios. Pero en cualquier caso, cada memoria asignada usandomalloc()
ocalloc()
debe liberarse luego usandofree()
free(NULL)
probando el punteroNULL
antes de llamarfree()
Todas las versiones de la biblioteca C que cumplen con los estándares tratan gratis (NULL) como no operativo.
Dicho esto, en un momento hubo algunas versiones de free que fallarían en free (NULL), por lo que es posible que vea algunas técnicas de programación defensiva recomendadas:
fuente
dice la documentación.
fuente
Recuerdo trabajar en PalmOS donde se
free(NULL)
bloqueó.fuente
NULL
fue una de las grandes diferencias de ejecución de la caja de herramientas de Palm en comparación con la biblioteca estándar.Puede eliminar de forma segura un puntero NULL. En ese caso, no se realizará ninguna operación. En otras palabras, free () no hace nada en un puntero NULL.
fuente
Uso recomendado:
Ver:
Cuando coloque el puntero en
NULL
despuésfree()
, podráfree()
volver a llamarlo y no se realizará ninguna operación.fuente
free(NULL)
es perfectamente legal en C así comodelete (void *)0
ydelete[] (void *)0
son legales en C ++.Por cierto, liberar memoria dos veces suele causar algún tipo de error en tiempo de ejecución, por lo que no corrompe nada.
fuente
delete 0
no es legal en C ++.delete
Requiere explícitamente una expresión de tipo puntero. Es legal aplicardelete
a un valor de puntero nulo escrito, pero no a0
(y no aNULL
).void*
: P ¿Qué destructor (es) debería ejecutar?void *
siempre que sea un puntero nulo.buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1);
- aquí, si no tiene suerte, buf2 obtuvo exactamente la misma dirección que buf1, y accidentalmente liberó buf1 dos veces, por lo que en la segunda liberación de buf1 realmente liberó buf2 en silencio, sin casu cualquier error (inmediato) / accidente / lo que sea. (pero es probable que la próxima vez que intente usar buf2 aún tenga un bloqueo, y este escenario es muy poco probable si se ejecuta en ASLR)free(ptr)
is save in C ifptr
isNULL
, sin embargo, lo que la mayoría de la gente no sabe es queNULL
no tiene por qué ser igual a 0. Tengo un buen ejemplo de la vieja escuela: en el C64, en la dirección 0, hay un puerto IO. Si escribió un programa en C para acceder a este puerto, necesitaría un puntero cuyo valor sea 0. La biblioteca C correspondiente tendría que distinguir entre 0 yNULL
luego.Saludos cordiales.
fuente
no la corrupción de la memoria, pero el comportamiento depende de la implementación. Por norma, debería ser un código legal.
fuente
ptr apunta a alguna ubicación de memoria, digamos 0x100.
Cuando libera (ptr), básicamente está permitiendo que el administrador de memoria use 0x100 para otra actividad o proceso y, en palabras simples, es la desasignación de recursos.
Cuando hace ptr = NULL, está haciendo que ptr apunte a una nueva ubicación (no nos preocupemos por lo que es NULL). Al hacer esto, perdió la pista de los datos de la memoria 0x100. Esto es lo que es la pérdida de memoria.
Por lo tanto, no es recomendable utilizar ptr = NULL en un ptr válido.
En su lugar, podría hacer una verificación segura usando:
if (ptr! = NULL) {free (ptr);}
Cuando liberas (ptr) donde ptr ya apunta a NULL, no realiza ninguna operación, por lo que es seguro hacerlo.
fuente