item how from example delete data c++ function exception vector stl

c++ - how - ¿Puedo confiar en vector:: size después de lanzar una excepción?



vector c++ (2)

Estoy tratando de entender cómo las excepciones afectan un std::vector . Más precisamente, quiero verificar el tamaño del vector cuando se lanza una excepción de falta de memoria.

Quiero decir algo como esto:

std::vector<int> v; try { for(unsigned int i = 0; i < desiredSize; ++i) v.push_back(i); } catch (const std::bad_alloc&) { cerr << "Out of memory! v.size() = " << v.size() << endl; exit(EXIT_FAILURE); }

¿Es ese un buen enfoque o debería hacer un seguimiento del tamaño del vector con una variable independiente de la mía?


De la documentación para std::vector::push_back :

Si se lanza una excepción (que puede deberse a Allocator::allocate() o elemento copy / move constructor / assignment), esta función no tiene ningún efecto (fuerte garantía de excepción).

Por lo tanto, en caso de falla, se push_back el último push_back que causó la excepción, pero todo lo demás estará bien: su vector contendrá todos los elementos previamente insertados y estará en un estado consistente.


De acuerdo con [vector.modifiers] (el énfasis es mío):

Observaciones: Causa la reasignación si el nuevo tamaño es mayor que la capacidad anterior. La reasignación invalida todas las referencias, punteros e iteradores que hacen referencia a los elementos en la secuencia. Si no se realiza una reasignación, todos los iteradores y referencias anteriores al punto de inserción permanecen válidos. Si se lanza una excepción que no sea el constructor de copia, mueva el constructor, el operador de asignación o el operador de asignación de movimiento de T o, por cualquier operación de InputIterator , no haya efectos. Si se lanza una excepción al insertar un elemento individual al final y T es CopyInsertable o is_nothrow_move_constructible_v<T> es verdadero, no hay efectos. De lo contrario, si el constructor de movimientos de una T CopyInsertable una CopyInsertable , los efectos no se especifican.

Dado que su T es int (y las operaciones en enteros nunca se lanzan) solo puede obtener los errores de falta de memoria de std::vector cuando intenta asignar memoria nueva para su contenido, por lo tanto, esta función no tiene efecto al arrojar cualquier excepción y usar size() luego es un enfoque perfectamente válido.