I am trying to understand how exceptions affect an std::vector
. More precisely, I want to check the size of the vector, when an out of memory exception is thrown.
I mean something like this:
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); }
Is that a good approach or should I keep track of the vector's size with an independent variable of mine?
When an exception is thrown using the throw keyword, the flow of execution of the program is stopped and the control is transferred to the nearest enclosing try-catch block that matches the type of exception thrown. If no such match is found, the default exception handler terminates the program.
Yes, size is decreased as you erase elements. Returns the number of elements in the vector.
In this case, all the elements are deleted, but the name of the vector is not deleted. The second way to delete a vector is just to let it go out of scope. Normally, any non-static object declared in a scope dies when it goes out of scope. This means that the object cannot be accessed in a nesting scope (block).
We can set the size of a Vector using setSize() method of Vector class. If new size is greater than the current size then all the elements after current size index have null values. If new size is less than current size then the elements after current size index have been deleted from the Vector.
From the documentation for std::vector::push_back
:
If an exception is thrown (which can be due to
Allocator::allocate()
or element copy/move constructor/assignment), this function has no effect (strong exception guarantee).
So in case of failure, the last push_back
which caused the exception will be rolled back, but everything else will be fine: your vector will contain all of the previously pushed elements, and will be in a consistent state.
According to [vector.modifiers] (emphasis mine):
Remarks: Causes reallocation if the new size is greater than the old capacity. Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. If no reallocation happens, all the iterators and references before the insertion point remain valid. If an exception is thrown other than by the copy constructor, move constructor, assignment operator, or move assignment operator of
T
or by anyInputIterator
operation there are no effects. If an exception is thrown while inserting a single element at the end andT
isCopyInsertable
oris_nothrow_move_constructible_v<T>
is true, there are no effects. Otherwise, if an exception is thrown by the move constructor of a non-CopyInsertable
T
, the effects are unspecified.
Since your T
is int
(and operations on integers never throw) you can only get the out-of-memory errors from std::vector
when it attempts to allocate new memory for its contents, hence this function has no effect when throwing any exception and using size()
afterwards is a perfectly valid approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With