c++ - puntero - ¿Cómo verificar fallas en la asignación de memoria con un nuevo operador?
punteros c++ pdf (4)
Aún deberá comprobar si hay un error en la asignación de memoria.
Ya sea
scoped_array<char> buf;
try {
buf.reset( new char[MAX_BUF] );
} catch( std::bad_alloc& ) {
// Handle the failure
}
O
scoped_array<char> buf( new(std::nothrow)char[MAX_BUF] );
if( buf.get() == NULL ) {
// Handle the failure
}
Hace poco cambié el lenguaje de mi proyecto para usar C ++ de C. Con C, usé malloc y luego verifico si malloc tuvo éxito pero con C ++, uso ''new'' para asignar memoria y me gustaría saber cómo Normalmente se comprueba el error de asignación de memoria.
Desde mi búsqueda en google, vi como se ve lo siguiente.
char *buf = new (nothrow)char[10];
También vi lo siguiente.
try{} catch(bad_alloc&) {}
Pero ¿qué pasa con lo siguiente? Estoy usando algunas de las rutinas de la biblioteca de Chrome para usar punteros inteligentes.
Por ejemplo, tengo el código de la siguiente manera.
scoped_array<char> buf(new char[MAX_BUF]);
Es genial usar punteros inteligentes, pero simplemente no estoy seguro de cómo debo verificar si la asignación de memoria fue exitosa. ¿Debo dividirme en dos sentencias separadas con nothrow o try / catch? ¿Cómo hace normalmente estos controles en C ++?
Cualquier consejo será apreciado.
Bueno, llamas a new que lanza bad_alloc
, así que debes atraparlo:
try
{
scoped_array<char> buf(new char[MAX_BUF]);
...
}
catch(std::bad_alloc&)
{
...
}
o
scoped_array<char> buf(new(nothrow) char[MAX_BUF]);
if(!buf)
{
//allocation failed
}
Lo que quiero decir con mi respuesta es que los punteros inteligentes propagan excepciones. Entonces, si está asignando memoria con un lanzamiento normal nuevo, debe capturar una excepción. Si está realizando una asignación con un nothrow nuevo, debe verificar que no haya nullptr
. En cualquier caso, los punteros inteligentes no añaden nada a esta lógica.
En C ++ hay 2 formas principales en las que una new
asigna memoria y cada una requiere una verificación de errores diferente.
El new
operador estándar lanzará una excepción std::bad_alloc
en caso de error y esto se puede manejar como una excepción normal
try {
char* c = new char[100];
} catch (std::bad_alloc&) {
// Handle error
}
O como alternativa, la nothrow
versión de nothrow
simplemente devolverá NULL
falla.
char* c = new (std::nothrow) char[100];
if (!c) {
// Handle error
}
Sin embargo, tengo curiosidad por saber qué espera hacer cuando falla la asignación. Si no hay memoria disponible para asignar su objeto, a menudo hay muy poco que se puede hacer en el proceso.
Odio decirlo, pero en mi opinión, vas en la dirección equivocada (y, desafortunadamente, las otras respuestas que recibiste tampoco te han indicado en la dirección correcta).
En lugar de elegir entre las diferentes variedades de punteros inteligentes y / o normales frente a las variantes new
, probablemente debería retroceder al menos dos pasos más de lo que está haciendo y reemplazar sus estructuras de datos dinámicos administrados manualmente con colecciones. Puede que esta no sea siempre la opción correcta, pero al menos en mi experiencia, es la forma correcta de hacerlo con más frecuencia que no. La biblioteca estándar tiene varias posibilidades (vector, deque, lista, conjunto, etc.), y es muy probable que pueda utilizar una de ellas en lugar de tratar directamente con las new
empresas.
Por defecto, usarán un asignador que terminará usando la variante normal (lanzamiento) de new
. Por lo tanto, normalmente desea poner la mayoría del código en un bloque de try
a un nivel bastante alto, y tiene una cláusula catch
que trata de haberse quedado sin memoria allí.
Cuando / si necesita lidiar con la asignación de memoria directamente, es muy probable que aún desee proporcionar una interfaz similar a la de los contenedores estándar en la biblioteca, de modo que funcionará con los algoritmos e iteradores normales. Su experiencia inicial con el uso de los contenedores existentes se verá bien cuando llegue a este punto, aunque puede ser un camino en el futuro.