operador new, operador new[]
Definido en el archivo de encabezado <new>
|
||||||
funciones de asignación reemplazables
|
||||||
void* operator new ( std::size_t count ); |
(1) | |||||
void* operator new[]( std::size_t count ); |
(2) | |||||
void* operator new ( std::size_t count, std::align_val_t al ); |
(3) | (desde C++17) | ||||
void* operator new[]( std::size_t count, std::align_val_t al ); |
(4) | (desde C++17) | ||||
funciones de asignación reemplazables que no lanzan
|
||||||
void* operator new ( std::size_t count, const std::nothrow_t& tag ); |
(5) | |||||
void* operator new[]( std::size_t count, const std::nothrow_t& tag ); |
(6) | |||||
void* operator new ( std::size_t count, std::align_val_t al, const std::nothrow_t& ); |
(7) | (desde C++17) | ||||
void* operator new[]( std::size_t count, std::align_val_t al, const std::nothrow_t& ); |
(8) | (desde C++17) | ||||
funciones de asignación de ubicación que no asignan
|
||||||
void* operator new ( std::size_t count, void* ptr ); |
(9) | |||||
void* operator new[]( std::size_t count, void* ptr ); |
(10) | |||||
funciones de asignación de ubicación definidas por el usuario |
||||||
void* operator new ( std::size_t count, user-defined-args... ); |
(11) | |||||
void* operator new[]( std::size_t count, user-defined-args... ); |
(12) | |||||
void* operator new ( std::size_t count, std::align_val_t al, user-defined-args... ); |
(13) | (desde C++17) | ||||
void* operator new[]( std::size_t count, std::align_val_t al, user-defined-args... ); |
(14) | (desde C++17) | ||||
funciones de asignación específicas de la clase |
||||||
void* T::operator new ( std::size_t count ); |
(15) | |||||
void* T::operator new[]( std::size_t count ); |
(16) | |||||
void* T::operator new ( std::size_t count, std::align_val_t al ); |
(17) | (desde C++17) | ||||
void* T::operator new[]( std::size_t count, std::align_val_t al ); |
(18) | (desde C++17) | ||||
funciones de asignación de ubicación específicas de la clase |
||||||
void* T::operator new ( std::size_t count, user-defined-args... ); |
(19) | |||||
void* T::operator new[]( std::size_t count, user-defined-args... ); |
(20) | |||||
void* T::operator new ( std::size_t count, std::align_val_t al, user-defined-args... ); |
(21) | (desde C++17) | ||||
void* T::operator new[]( std::size_t count, std::align_val_t al, user-defined-args... ); |
(22) | (desde C++17) | ||||
Asigna el número de bytes requerido. Estas funciones de asignación se llaman por las expresiones new para asignar memoria en la cual se inicializa un nuevo objeto . También pueden llamarse usando la sintaxis de llamada a función regular.
count
bytes de la reserva disponible. En caso de falla, la implementación de la biblioteca estándar llama al puntero de función devuelto por std::get_new_handler y repite los intentos de asignación hasta que el nuevo controlador no regrese o se convierta en un puntero nulo, momento en el cual lanza std::bad_alloc. Se requiere que esta función devuelva un puntero adecuadamente alineado para apuntar a un objeto del tamaño solicitado.__STDCPP_DEFAULT_NEW_ALIGNMENT__
.__STDCPP_DEFAULT_NEW_ALIGNMENT__
.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. La implementación de la biblioteca estándar llama a la versión (3) y devuelve un puntero nulo en caso de error en lugar de propagar la excepción. __STDCPP_DEFAULT_NEW_ALIGNMENT__
. La implementación de la biblioteca estándar llama a la versión (4) y devuelve un puntero nulo en caso de error en lugar de propagar la excepción.ptr
sin modificar. El comportamiento no está definido si esta función se llama a través de una expresión new
de ubicación y ptr
es un puntero nulo. ptr
sin modificar. El comportamiento no está definido si esta función se llama a través de una expresión new
de ubicación y ptr
es un puntero nulo. new
de ubicación está mal formada.new
de ubicación está mal formada.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si se define una versión específica de la clase ((15) o (17)), se llama en su lugar. Si no se proporciona ni una versión específica de la clase ni un formato global de ubicación que soporte alineación, en su lugar se busca el formato (11) sin soporte de alineación.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si se define una versión específica de la clase ((16) o (18)), se llama en su lugar. Si no se proporciona ni una versión específica de la clase ni un formato global de ubicación que soporte alineación, en su lugar se busca el formato (12) sin soporte de alineación.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si no se proporciona esta sobrecarga, pero se provee el formato (15) de miembro que no soporta un asignador, en su lugar se llama a la sobrecarga de miembro que no soporta un asignador.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si no se proporciona esta sobrecarga, pero se provee el formato (16) de miembro que no soporta un asignador, en su lugar se llama a la sobrecarga de miembro que no soporta un asignador.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si no se proporciona esta sobrecarga, pero se provee el formato (19) de miembro que no soporta un asignador, en su lugar se llama a la sobrecarga de miembro que no soporta un asignador.__STDCPP_DEFAULT_NEW_ALIGNMENT__
. Si no se proporciona esta sobrecarga, pero se provee el formato (20) de miembro que no soporta un asignador, en su lugar se llama a la sobrecarga de miembro que no soporta un asignador.Contenido |
[editar] Parámetros
count | - | Número de bytes a asignar. |
ptr | - | Puntero a un área de memoria en la cual initializer el objeto. |
tag | - | Etiqueta de desambiguación utilizada para seleccionar sobrecargas que no lanzan excepciones. |
al | - | Alineamiento a usar. El comportamiento es indefinido si éste no es un valor de alineamiento válido. |
[editar] Valor de retorno
size
.size
, o puntero nulo si hubo falla al asignar.ptr
.[editar] Excepciones
[editar] Reemplazos globales
Las versiones (1-4) se declaran implícitamente en cada unidad de traducción aun cuando el archivo de encabezado <new>
no se incluya. Las versiones (1-8) son reemplazables: una función miembro proporcionada por el usuario con la misma signatura definida en cualquier parte del programa, en cualquier archivo fuente, reemplaza a la versión por defecto. Su declaración no necesita ser visible.
El comportamiento es indefinido si se proporciona más de un reemplazo en el programa para cualquier función de asignación reemplazable, o si un reemplazo se define con el especificador inline
. El programa está mal formado si se define un reemplazo en un espacio de nombres que no sea el espacio de nombres global, o si se define como una función estática no miembro en el ámbito global.
La implementación de la biblioteca estándar para las versiones |
(desde C++11) |
#include <cstdio> #include <cstdlib> #include <new> // reemplazo de un conjunto mínimo de funciones: void* operator new(std::size_t sz) { std::printf("se ha llamado al op new global, size = %zu\n", sz); void *ptr = std::malloc(sz); if (ptr) return ptr; else throw std::bad_alloc{}; } void operator delete(void* ptr) noexcept { std::puts("se ha llamado al op delete global"); std::free(ptr); } int main() { int* p1 = new int; delete p1; int* p2 = new int[10]; // se garantiza que llama al reemplazo en C++11 delete[] p2; }
Posible salida:
se ha llamado al op new global, size = 4 se ha llamado al op delete global se ha llamado al op new global, size = 40 se ha llamado al op delete global
Las sobrecargas de operator new
y operator new[]
con parámetros adicionales definidos por el usuario ("los formatos de ubicación", versiones (11-14)) pueden declararse en el ámbito global como es habitual, y se llaman por los formatos de ubicación de expresiones new coincidentes.
Los formatos de ubicación del operador new
de la biblioteca estándar que no asignan (9-10), no pueden reemplazarse y solamente pueden ser personalizados si la expresión new
de ubicación no utilizó la nueva sintaxis ::new
, al proporcionar un new de ubicación específico de la clase (19,20) con una signatura coincidente: void* T::operator new(size_t, void*)
o void* T::operator new[](size_t, void*)
.
El formato de ubicación |
(desde C++14) |
[editar] Sobrecargas específicas de la clase
Las funciones de asignación de memoria tanto de objetos únicos como arrays pueden definirse como funciones miembro estáticas públicas de una clase (versiones (15-18)). Si se definen, estas funciones de asignación se llaman por las expresiones new para asignar memoria para objetos únicos y arrays de esa clase, a menos que la expresión new
haya utilizado el formato ::new
, que pasa por alto la búsqueda en el ámbito de la clase. La palabra clave static
es opcional para estas funciones: independientemente de si se usa o no, la función de asignación es una función miembro estática.
La expresión new
busca el nombre de la función de asignación apropiada primero en el ámbito de la clase, y después en el ámbito global. Observa que debido a las reglas de búsqueda de nombres, cualquier función de asignación declarada en el ámbito de la clase oculta todas las funciones de asignación globales para las expresiones new
que intenten asignar objetos de esta clase.
Al asignar objetos y arrays de objetos cuya alineación excede de |
(desde C++17) |
#include <iostream> // funciones de asignación específicas de la clase struct X { static void* operator new(std::size_t sz) { std::cout << "new personalizado con " << sz << " bytes" << '\n'; return ::operator new(sz); } static void* operator new[](std::size_t sz) { std::cout << "new personalizado con " << sz << " bytes" << '\n'; return ::operator new(sz); } }; int main() { X* p1 = new X; delete p1; X* p2 = new X[10]; delete[] p2; }
Posible salida:
new personalizado con 1 bytes new personalizado con 10 bytes
Las sobrecargas de operator new
y operator new[]
con parámetros adicionales definidos por el usuario ("formatos de ubicación"), también pueden definirse como miembros de la clase (19-22)). Cuando la expresión new
con la signatura coincidente busca la función de asignación correspondiente para llamarla, comienza en el ámbito de la clase antes de examinar el ámbito global, y si se proporciona un new
de ubicación específico de la clase, se llama.
Al asignar objetos y arrays de objetos cuya alineación excede de |
(desde C++17) |
#include <stdexcept> #include <iostream> struct X { X() { throw std::runtime_error(""); } // new de ubicación personalizado static void* operator new(std::size_t sz, bool b) { std::cout << "se ha llamado a new de ubicación personalizado, b = " << b << '\n'; return ::operator new(sz); } // delete de ubicación personalizado static void operator delete(void* ptr, bool b) { std::cout << "se ha llamado a delete de ubicación personalizado, b = " << b << '\n'; ::operator delete(ptr); } }; int main() { try { X* p1 = new (true) X; } catch(const std::exception&) { } }
Salida:
se ha llamado a new de ubicación personalizado, b = 1 se ha llamado a delete de ubicación personalizado, b = 1
Si operator new
al nivel de la clase es una plantilla de función, debe tener un tipo de retorno de void*
, el primer argumento debe ser std::size_t
, y debe tener dos o más parámetros. En otras palabras, solamente los formatos de ubicación pueden ser plantillas.
[editar] Véase también
Funciones de desasignación. (función) | |
(C++11) |
Obtiene el nuevo controlador actual. (función) |
Registra un controlador nuevo. (función) | |
(en desuso en C++17)(eliminado en C++20) |
Obtiene almacenamiento sin inicializar. (plantilla de función) |
Asigna memoria (función) | |
(C++17) |
Asigna memoria alineada (función) |
[editar] Referencias
- El estándar C++11 (ISO/IEC 14882:2011):
- 18.6 Administración de memoria dinámica [support.dynamic]