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) |
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
|