Namespaces
Variants

std:: realloc

From cppreference.net
< cpp ‎ | memory ‎ | c
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Definido en el encabezado <cstdlib>
void * realloc ( void * ptr, std:: size_t new_size ) ;

Reasigna el área de memoria dada ( creando implícitamente objetos en el área de destino). Debe haber sido previamente asignada por std::malloc , std::calloc o std::realloc y no haber sido liberada con std::free , 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 un puntero nulo, el comportamiento es el mismo que llamar a std:: malloc ( new_size ) .

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 anterior puede o no liberarse) o puede devolverse algún puntero no nulo que no pueda utilizarse para acceder al almacenamiento. Este uso está obsoleto (mediante C DR 400 ). (desde C++20)

Las siguientes funciones deben ser seguras para hilos (thread-safe):

Las llamadas a estas funciones que asignan o liberan una unidad particular de almacenamiento ocurren en un único orden total, y cada llamada de liberación happens-before la siguiente asignación (si existe) en este orden.

(desde C++11)

Contenidos

Parámetros

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

Valor de retorno

En caso de éxito, retorna un puntero al inicio de la memoria recién asignada. Para evitar una fuga de memoria, el puntero retornado debe ser desasignado con std::free o std::realloc . El puntero original ptr queda invalidado y cualquier acceso al mismo constituye comportamiento indefinido (incluso si la realocación se realizó in-situ).

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

Notas

Debido a que la reubicación puede implicar copia byte a byte (independientemente de si expande o contrae el área), es necesario (pero no suficiente) que esos objetos sean de tipo TriviallyCopyable .

Algunas bibliotecas no estándar definen un rasgo de tipo "BitwiseMovable" o "Relocatable", que describe un tipo que no tiene:

  • referencias externas (por ejemplo, nodos de una lista o un árbol que contienen referencia a otro elemento), y
  • referencias internas (por ejemplo, puntero miembro que podría contener la dirección de otro miembro).

Los objetos de este tipo pueden ser accedidos después de que su almacenamiento sea reasignado incluso si sus constructores de copia no son triviales.

Ejemplo

#include <cassert>
#include <cstdlib>
#include <new>
class MallocDynamicBuffer
{
    char* p;
public:
    explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr)
    {
        resize(initial);
    }
    ~MallocDynamicBuffer() { std::free(p); }
    void resize(std::size_t newSize)
    {
        if (newSize == 0) // esta verificación no es estrictamente necesaria,
        {
            std::free(p); // pero realloc de tamaño cero está obsoleto en C
            p = nullptr;
        }
        else
        {
            if (void* mem = std::realloc(p, newSize))
                p = static_cast<char*>(mem);
            else
                throw std::bad_alloc();
        }
    }
    char& operator[](size_t n) { return p[n]; }
    char operator[](size_t n) const { return p[n]; }
};
int main()
{
    MallocDynamicBuffer buf1(1024);
    buf1[5] = 'f';
    buf1.resize(10); // reducir
    assert(buf1[5] == 'f');
    buf1.resize(1024); // aumentar
    assert(buf1[5] == 'f');
}

Véase también