std::realloc
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:
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.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) |
Contenido |
[editar] Parámetros
ptr | - | Puntero al área de memoria que se va a reasignar. |
new_size | - | Nuevo tamaño del array. |
[editar] 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().
[editar] 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.
[editar] 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'); }
[editar] Véase también
Documentación de C para realloc
|