Pregunta

Sé que según el estándar C ++ en caso de que la nueva no puede asignar la memoria que se supone que tirar std :: bad_alloc excepción. Pero he oído que algunos compiladores como VC6 (o aplicación CRT?) No se adhieren a ella. Es esto cierto ? Me pregunto porque la comprobación de NULL después de cada nueva declaración hace que el código se ve muy feo.

¿Fue útil?

Solución

VC6 era no conforme de forma predeterminada en este sentido. new de VC6 volvió 0 (o NULL).

Aquí está el artículo de Microsoft KB sobre este tema, junto con su solución sugerida utilizando un controlador new personalizado:

Si tiene código antiguo que fue escrito por el comportamiento VC6, se puede conseguir que el mismo comportamiento con los nuevos compiladores MSVC (algo así como 7.0 y posterior) mediante la vinculación de una nothrownew.obj llamado fichero objeto. En realidad hay un conjunto bastante complicada de reglas en el 7.0 y 7.1 compiladores (VS2002 y VS2003) para determinar si por defecto en no-lanzamiento o new tirar.

Parece que MS limpiar esto en 8,0 (VS2005) -ahora siempre por defecto a un nuevo lanzamiento a menos que se vincula específicamente a nothrownew.obj.

Tenga en cuenta que puede especificar que desea new para volver 0 en vez de tirar std::bad_alloc utilizando el parámetro std::nothrow:

SomeType *p = new(std::nothrow) SomeType;

Esto parece funcionar de VC6, por lo que podría ser una manera más o menos mecánicamente fijar el código para trabajar lo mismo con todos los compiladores por lo que no tiene que reelaborar el tratamiento de errores existentes.

Otros consejos

Me gustaría añadir el (algo controvertido) opinión de que la comprobación de NULL después de un intento de asignación es más o menos un ejercicio de futilidad. Si el programa se ejecuta siempre en esa situación, lo más probable es que no se puede hacer mucho más que salir rápido. Es muy probable que cualquier intento posterior asignación también se producirá un error.

Sin comprobación de NULL, el código siguiente intentaría referencia a un puntero NULL, que tiende a salir del programa rápido, con una condición de salida relativamente único (y fácilmente depurable).

No estoy tratando de convencerlo de comprobación de NULL, es sin duda la programación de conciencia. Pero no se gana mucho de él, a no ser en casos muy específicos donde se puede almacenar tal vez alguna información de recuperación (sin asignar más memoria), o libre de memoria menos importante, etc, pero esos casos será relativamente raro para la mayoría de la gente.

En vista de esto, que acababa de confiar en el compilador para lanzar bad_alloc, personalmente -. Por lo menos en la mayoría de los casos

Sobre la base de la especificación C ++, siempre va a lanzar std :: bad_alloc cuando se utiliza simplemente nuevo sin parametros, pero por supuesto no puede haber algunos compiladores no conformes.

No lo haría código para que sea compatible con los compiladores de C ++ no compatible sin embargo. VC6 siendo uno de ellos a este respecto.

Es una buena práctica a pesar de que siempre su puntero a NULL después de que los elimine. Así que debido a eso, la comprobación de NULL sigue siendo necesaria.

Una vez dicho esto, aquí hay un par de opciones a la limpieza de su código:

Opción 1: Ajuste su propio nuevo manejador

Una manera segura para limpiar su código sería llamar a: set_new_handler primero.

A continuación, puede comprobar NULL en el controlador y tirar std :: bad_alloc allí si se devuelve NULL.

Si te gusta excepciones mejor, entonces esta es la mejor opción. Si te gusta a devolver NULL mejor, entonces también puede hacer que al hacer una atrapada dentro de su nuevo controlador.

Opción 2: Uso sobrecargado nuevo

El archivo de cabecera C ++ estándar define un nothrow struct que está vacío. Se puede utilizar un objeto de esta estructura en el interior nueva para obtener su versión sobrecargada que siempre devuelve NULL.

void* operator new (size_t size, const std::nothrow_t &);
void* operator new[] (void *v, const std::nothrow_t &nt);

Así que en su código:

 char *p = new(std::nothrow) char[1024];

A continuación se una buena refrence para la lectura adicional

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top