Espacios de nombres
Variantes

std::realloc

De cppreference.com
< cpp | memory | c
 
 
Biblioteca de servicios
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
(C++20)
(C++11)
(C++11)
 
<tbody> </tbody>
Definido en el archivo de encabezado <cstdlib>
void* realloc( void* ptr, std::size_t new_size );

Reasigna el área de memoria dada. Debe haber sido previamente asignada mediante std::malloc(), std::calloc() o std::realloc() y aún no haber sido liberada con std::free(), de lo contrario, el resultado no está definido.

La reasignación se realiza mediante:

a) la expansión o contracción del área existente a la que apunta ptr, si es posible. El contenido del área permanece sin cambios hasta el menor de los tamaños nuevos y antiguos. Si el área se expande, el contenido de la nueva parte del array no está definido.
b) la asignación de un nuevo bloque de memoria de tamaño new_size bytes, copiando el área de memoria con un tamaño igual al menor entre el nuevo y el antiguo, y liberando el antiguo bloque.

Si no hay suficiente memoria, el antiguo bloque de memoria 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: se puede devolver un puntero nulo (en cuyo caso, el antiguo bloque de memoria puede liberarse o no) o se puede devolver un puntero no nulo que puede no ser utilizado para acceder al almacenamiento. Tal uso está obsoleto (mediante C DR 400). (desde C++20)

Se requiere que las siguientes funciones sean seguras frente a hilos:

Las llamadas a estas funciones que asignan o desasignan una unidad de almacenamiento particular ocurren en un orden total único, y cada llamada de desasignación sucede-antes que la siguiente asignación (si es que la hay) en este orden.

(desde C++11)

Parámetros

ptr - Puntero al área de memoria que se va a reasignar.
new_size - Nuevo tamaño del array.

Valor de retorno

En caso de éxito, devuelve un puntero al comienzo de la memoria recién asignada. Para evitar una fuga de memoria, el puntero devuelto debe desasignarse con std::free(), el puntero original ptr se invalida y cualquier acceso a él es comportamiento no definido (incluso si la reasignación fue en sitio).

En caso de error, devuelve un puntero nulo. El puntero original ptr sigue siendo válido y es posible que deba desasignarse con std::free().

Notas

Debido a que la reasignación puede implicar la copia de bytes (independientemente de si es para expandir o contraer), solo los objetos de tipos TriviallyCopyable son seguros para acceder en la parte preservada del bloque de memoria después de una llamada a realloc.

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 contiene referencias a otro elemento), y
  • referencias internas (por ejemplo, puntero a miembro que podría contener la dirección de otro miembro).

Se puede acceder a objetos de este tipo después de reasignar su almacenamiento, incluso si sus constructores de copia no son triviales.

Ejemplo

#include <cstdlib>
#include <new>
#include <cassert>

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 la realloc de tamaño cero está obsoleta 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); // contraer
    assert(buf1[5] == 'f');
    buf1.resize(1024); // expandir
    assert(buf1[5] == 'f');
}


Véase también

Documentación de C para realloc