Does the standard guarantee that string::erase
and string::pop_back
DO NOT reallocate memory? After erasing some elements, is it possible that the string
might be shrink automatically?
I checked the standard, it says that string::erase
and string::pop_back
either throw std::out_of_range
or throw nothing. Can I take that as a guarantee that these methods DO NOT do any reallocation? Since the reallocation might throw bad_alloc
.
No, sensible implementations might not reallocate but the standard does not guarantee that these method calls do not reallocate, the standard says on the requirements:
References, pointers, and iterators referring to the elements of a
basic_string
sequence may be invalidated by the following uses of that basic_string object:(4.1) as an argument to any standard library function taking a reference to non-const basic_string as an argument.227
(4.2) Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.
Both proposed methods fall under category 2 and thus both might change capacity()
which would implicitly mean a reallocation.
pop_back
is required to have the same effect as erase
as erase
is specified as :
Effects: Determines the effective length xlen of the string to be removed as the smaller of
n
andsize() - pos
. 3The function then replaces the string controlled by
*this
with a string of lengthsize() - xlen
whose firstpos
elements are a copy of the initial elements of the original string controlled by*this
, and whose remaining elements are a copy of the elements of the original string controlled by*this
beginning at positionpos + xlen
.
There's no guarantee on how that copy is made, extra allocations or reallocations are thus possible.
As for
Can I take that as a guarantee that these methods DO NOT do any reallocation? Since the reallocation might throw
bad_alloc
.
The standard does not seem to explicitly mention the possibility of a bad_alloc
caused by any of the methods. Even with a binding reserve
call there is no mention of it:
void reserve(size_type res_arg=0);
Throws:
length_error
ifres_arg > max_size()
Thus I don't think that assumption can be made.
Yes, you may assume that the Throws: on these functions prohibits reallocation (which could throw bad_alloc
).
20.5.5.12 Restrictions on exception handling [res.on.exception.handling]
Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph, or of a type derived from a type named in the Throws: paragraph that would be caught by an exception handler for the base type.
...
Functions defined in the C++ standard library that do not have a Throws: paragraph but do have a potentially- throwing exception specification may throw implementation-defined exceptions.186 Implementations should report errors by throwing exceptions of or derived from the standard exception classes (21.6.3.1, 21.8, 22.2).
Note that the spec does not explicitly say that something marked with a "Throws: Nothing." can't throw anything. But at some point common sense has to take over. The standard also doesn't explicitly state that these functions can't reformat your disk. In general the standard specifies what the functions can do, and they are not allowed to do anything else.
The only way a function throws an exception not listed in the Throws: spec (or a derived type) is if the client uses it in a way that invokes undefined behavior.
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