resueltos punteros memoria matrices estatica ejercicios dinamica aprender c undefined-behavior realloc

punteros - Realloc en puntero de valor nulo(o indefinido)



punteros en c youtube (3)

¿Existe algún peligro al asignar memoria usando realloc usando la ptr inicialmente con valor NULL?

No, eso sería exactamente como un malloc .

Si en lugar de:

int* ptr = NULL;

Tuve esto:

int* ptr; // no value given to ptr

¿Sería un problema llamar a realloc usando ptr?

Sí, habría un problema. Si realloc no obtiene un valor NULL , intentará expandir la memoria a partir de esa ubicación, o puede intentar free y hacer malloc otra parte de la memoria. Dado que las variables sin inicializar pueden tener cualquier valor , es muy probable que no sean un valor de realloc . Si tienes suerte, tu programa se bloquearía de inmediato.

Estaba leyendo sobre realloc y me confundí sobre un punto mencionado allí. Considere el siguiente código:

#include <stdio.h> #include <stdlib.h> int main () { int* ptr = NULL; ptr = realloc(ptr, 10*sizeof(int)); return 0; }

¿Existe algún peligro en la asignación de memoria con realloc usando la realloc con realloc NULL inicialmente? Si en lugar de:

int* ptr = NULL;

Tuve esto:

int* ptr; // no value given to ptr

¿Sería un problema llamar a realloc usando ptr ?


¿Existe algún peligro en la asignación de memoria con realloc utilizando la ptr de valor NULL inicialmente?

Ninguna

7.22.3.5

Si ptr es un puntero nulo, la función realloc se comporta como la función malloc para el tamaño especificado.

Para la segunda parte:

int* ptr; // no value given to ptr

¿Sería un problema llamar a realloc usando ptr?

Si está utilizando punteros sin inicializar, entonces ese es un problema muy serio, ya que no puede predecir cuál será su valor. La función realloc solo funciona correctamente para NULL o valores obtenidos de malloc / realloc .

De lo contrario, si ptr no coincide con un puntero devuelto por una función de administración de memoria, [...] el comportamiento no se define.


Con el código específico que se muestra, no hay ningún problema con el uso del puntero nulo inicialmente.

Si la variable ptr no está inicializada (no se establece en 0 o NULL), cualquier llamada a realloc() es peligrosa; el comportamiento no está definido y si tiene suerte, el programa se bloqueará, pero si tiene mala suerte, parecerá que funciona durante un tiempo, hasta que algo salga mal más adelante en el programa donde será difícil detectar el problema. En código ejecutado hace mucho tiempo.

Hay quienes argumentan que es mejor usar malloc() para la asignación inicial y realloc() partir de entonces. Hay algo de justicia en la sugerencia, entre otras cosas porque probablemente no utilice ptr = realloc(ptr, 0); para liberar la memoria, aunque podría hacerlo (por lo que realmente no necesita malloc() o free() porque realloc() puede hacer las tres operaciones). Pero el estándar C90 requiere que realloc(0, new_size) funcione de manera equivalente a malloc(new_size) , y no conozco ninguna biblioteca en C que se comporte de manera diferente (pero puede que haya algunas; solo he usado algunas bibliotecas en C, aunque principalmente los más utilizados).

Sin embargo, en un caso más general como el siguiente código, entonces hay un problema sutil con el código (pero no tiene que ver con el puntero nulo inicial):

#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *ptr = NULL; size_t len = 0; char buffer[256]; while (fgets(buffer, sizeof(buffer), stdin)) { size_t buflen = strlen(buffer) + 1; if (buflen > len) { if ((ptr = realloc(ptr, buflen)) == 0) // Danger! // ... handle memory allocation failure ... len = buflen; } strcpy(ptr, buffer); // ... do something with ptr } free(ptr); return 0; }

¿Cuál es el peligro? El peligro es que si la segunda o una asignación de memoria posterior falla y ptr es el único puntero a la memoria asignada, simplemente sobrescribió su valor anterior con nulo. Eso significa que no puede liberar la memoria asignada usando ptr más: ha ptr memoria. (Para la primera asignación, el valor inicial fue 0, el valor sobrescrito fue cero y nada ha cambiado; no hay pérdida de memoria. Por eso se agregó el bucle al código).

Regla de oro

  • No escriba ptr = realloc(ptr, newsize);

Guarde el nuevo valor en una variable separada hasta que lo haya probado.

#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *ptr = NULL; size_t len = 0; char buffer[256]; while (fgets(buffer, sizeof(buffer), stdin)) { size_t buflen = strlen(buffer) + 1; if (buflen > len) { char *new_ptr = realloc(ptr, buflen); if (new_ptr == 0) // ... handle memory allocation failure ... ptr = new_ptr; len = buflen; } strcpy(ptr, buffer); // ... do something with ptr } free(ptr); return 0; }

Este código no pierde memoria en un error de asignación.

Recomendación auxiliar: no use una variable llamada new ; Hará difícil compilar con un compilador de C ++. Incluso si no tiene la intención ahora de convertir a C ++ (y aunque probablemente termine reescribiendo la administración de memoria si lo hace), no hay ninguna virtud en usar la palabra clave C ++ new como un nombre de variable C ... a menos que desee explícitamente para evitar la compilación con un compilador de C ++.