2008-12-18 13 views

Respuesta

16

estándar El C++ tiene esto que decir acerca de la forma único objeto (la forma por lo general se utiliza) del nuevo operador de la <new> cabecera:

comportamiento requerido:

devolver un puntero no nulo a adecuadamente almacenamiento alineado (3.7.3), o bien lanzar una excepción bad_alloc . Este requisito es vinculante en una versión de reemplazo de esta función.

comportamiento por defecto:

- Ejecuta un bucle: Dentro del bucle, la función intenta primero para asignar el almacenamiento requerido. Si el intento implica una llamada a la función de biblioteca estándar C malloc no está especificado.

- Devuelve un puntero al almacenamiento asignado si el intento se realiza correctamente. De lo contrario, si el último argumento para set_new_handler() era un puntero nulo, ejecute bad_alloc.

- De lo contrario, la función llama al new_handler actual (18.4.2.2). Si la función llamada vuelve, el ciclo se repite.

- El ciclo finaliza cuando un intento de asignar el almacenamiento solicitado se realiza correctamente o cuando una función llamada new_handler no regresa.

La norma tiene un montón de otras cosas que decir sobre el nuevo operador y la asignación de memoria dinámica (muchísimo que decir), pero creo que la lista "El comportamiento por defecto", resume los aspectos básicos del nuevo operador bastante bien.

+1

¿Hay algo así como la forma en que el tamaño del objeto se almacena con el nuevo.Así que se puede utilizar al eliminar el objeto usando el puntero – yesraaj

+0

Esto seguramente queda para la implementación y lo hará ser diferente entre las plataformas. – Anteru

+0

Eso no está especificado por la norma. Normalmente se usará malloc() o algo similar y el tamaño del bloque de memoria se mantendrá utilizando el mismo tipo de técnicas (o idénticas si se usa malloc()). –

0

Depende si está sobrecargado o no, si creó la aplicación para la depuración, si está usando un detector de fugas de memoria, si tiene algún tipo de combinación de memoria, si tiene algo así como el recolector de basura Boehm marcar/desmarcar bits, etc., etc. Podría estar haciendo un montón de cosas personalizadas en el interior, o nada especial en absoluto.

+0

Creo que cubrió eso diciendo "Estándar" –

9

He escrito una explicación de lo que hace en this respuesta. En él se explica cómo

  • new tiene la memoria
  • new maneja fallo de memoria
  • new maneja excepciones constructor
  • new manijas de colocación especial y versiones nothrow

Michael explicó cómo la función de asignación por defecto (:: operator new) obtiene memoria muy bien y cómo maneja la falla. He visto tu pregunta sobre dónde se almacena el tamaño de un objeto en sus comentarios. La respuesta es que no hay un tamaño almacenado si no es necesario.Recuerde que C no necesita el tamaño de free (y operador :: nueva solo puede usar malloc):

void * memory = malloc(x); 
free (memory); // no need to tell it the size 

Aquí se muestra un ejemplo en el que ver cómo almacenar el tamaño tiene un impacto en el tamaño de la asignación de la forma array de una nueva expresión (no cubierto por mi otra respuesta):

#include <cstddef> 
#include <iostream> 

struct f { 
    // requests allocation of t bytes 
    void * operator new[](std::size_t t) throw() { 
     void *p = ::operator new[](t); 
     std::cout << "new p: " << p << std::endl; 
     std::cout << "new size: " << t << std::endl; 
     return p; 
    } 

    // requests deleting of t bytes starting at p 
    void operator delete[](void *p, std::size_t t) throw() { 
     std::cout << "delete p: " << p << std::endl; 
     std::cout << "size : " << t << std::endl; 
     return ::operator delete[](p); 
    } 
}; 

int main() { 
    std::cout << "sizeof f: " << sizeof (f) << std::endl; 

    f * f_ = new f[1]; 
    std::cout << "&f_  : " << f_ << std::endl; 
    delete[] f_; 
} 

se imprimirá algo como esto:

sizeof f: 1 
new p: 0x93fe008 
new size: 5 
&f_  : 0x93fe00c 
delete p: 0x93fe008 
size : 5 

una byt e para el objeto mismo y 4 bytes para el conteo que se almacena justo antes del área asignada del objeto. Ahora bien, si usamos la función de cancelación de asignación sin un parámetro de tamaño (apenas quitarlo del operador delete), obtenemos este resultado:

sizeof f: 1 
new p: 0x9451008 
new size: 1 
&f_  : 0x9451008 
delete p: 0x9451008 

El tiempo de ejecución de C++ que aquí no importa el tamaño, por lo que no hace almacenarlo más. Tenga en cuenta que esto es altamente específico para la implementación, y eso es lo que hace gcc aquí para poder decirle el tamaño en la eliminación del operador miembro. Otras implementaciones aún pueden almacenar el tamaño, y lo más probable es que exista un destructor para invocar para la clase. Por ejemplo, simplemente agregando ~f() { } arriba hace que gcc almacene el tamaño, independientemente de la función de desasignación que escribamos.

+0

¿Podría explicar la sintaxis de este 'operator delete []' con el tamaño al implementar un grupo de memoria, es decir, podría ayudarme con http://stackoverflow.com/questions/2322742? ¡Gracias! – Tobias

Cuestiones relacionadas