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 deInputIterator
, no haya efectos. Si se lanza una excepción al insertar un elemento individual al final yT
esCopyInsertable
ois_nothrow_move_constructible_v<T>
es verdadero, no hay efectos. De lo contrario, si el constructor de movimientos de unaT
CopyInsertable
unaCopyInsertable
, 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.