Namespaces
Variants

realloc

From cppreference.net
Definido en el encabezado <stdlib.h>
void * realloc ( void * ptr, size_t new_size ) ;

Reasigna el área de memoria dada. Si ptr no es NULL, debe haber sido previamente asignado por malloc , calloc o realloc y no haber sido liberado con una llamada a free o realloc . De lo contrario, los resultados son indefinidos.

La reasignación se realiza mediante una de las siguientes opciones:

a) expandiendo o contrayendo el área existente apuntada por ptr , si es posible. El contenido del área permanece sin cambios hasta el menor de los tamaños nuevo y antiguo. Si el área se expande, el contenido de la nueva parte del array está indefinido.
b) asignando un nuevo bloque de memoria de tamaño new_size bytes, copiando el área de memoria con tamaño igual al menor de los tamaños nuevo y antiguo, y liberando el bloque antiguo.

Si no hay suficiente memoria, el bloque de memoria anterior no se libera y se devuelve un puntero nulo.

Si ptr es NULL , el comportamiento es el mismo que llamar a malloc ( new_size ) .

De lo contrario,

si new_size es cero, el comportamiento está definido por la implementación (puede devolverse un puntero nulo (en cuyo caso el bloque de memoria antiguo puede liberarse o no), o puede devolverse algún puntero no nulo que no pueda usarse para acceder al almacenamiento). Este uso está obsoleto (mediante C DR 400 ). (desde C17)

(hasta C23)

si new_size es cero, el comportamiento no está definido.

(desde C23)

realloc es seguro para hilos: se comporta como si solo accediera a las ubicaciones de memoria visibles a través de su argumento, y no a ningún almacenamiento estático.

Una llamada previa a free o realloc que desasigna una región de memoria sincroniza-con una llamada a cualquier función de asignación, incluyendo realloc que asigna la misma o una parte de la misma región de memoria. Esta sincronización ocurre después de cualquier acceso a la memoria por la función desasignadora y antes de cualquier acceso a la memoria por realloc . Existe un único orden total de todas las funciones de asignación y desasignación que operan sobre cada región particular de memoria.

(desde C11)

Contenidos

Parámetros

ptr - puntero al área de memoria a ser reasignada
new_size - nuevo tamaño del array en bytes

Valor de retorno

En caso de éxito, retorna el puntero al inicio de la memoria recién asignada. Para evitar una fuga de memoria, el puntero retornado debe ser desasignado con free o realloc . El puntero original ptr queda invalidado y cualquier acceso al mismo es comportamiento indefinido (incluso si la realocación fue en el mismo lugar).

En caso de fallo, retorna un puntero nulo. El puntero original ptr permanece válido y puede necesitar ser desasignado con free o realloc .

Notas

Originalmente (en C89), se añadió soporte para tamaño cero para adaptarse a código como

OBJ *p = calloc(0, sizeof(OBJ)); // marcador de posición de "longitud cero"
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // reasignaciones hasta que el tamaño se estabilice
    /* código que puede cambiar c o salir del bucle */
}

Ejemplo

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
    free(next); // finally, frees the storage
    return EXIT_SUCCESS;
}

Salida posible:

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 7.22.3.5 La función realloc (p: TBD)
  • Estándar C17 (ISO/IEC 9899:2018):
  • 7.22.3.5 La función realloc (p: 254)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 7.22.3.5 La función realloc (p: 349)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 7.20.3.4 La función realloc (p: 314)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 4.10.3.4 La función realloc

Véase también