Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the C++ standard guarantee that std::string::resize(new_size) will not cause allocation if the new_size is not greater than the old one? [duplicate]

#include <string>
#include <cassert>

int main()
{
    auto s = "hello"s;
    auto p = &s[0];

    s.resize(3);
    assert('h' == *p); // always ok?
}

Does the C++ standard guarantee that std::string::resize(new_size) will not cause allocation if the new_size is not greater than the old one?

like image 624
xmllmx Avatar asked Aug 21 '19 09:08

xmllmx


2 Answers

Note first that standards normally set requirements rather than guarantees.

std::basic_string::resize is not required to not reallocate the string if resize argument is less than its current size(). In fact, the C++17 standard says that the current string is replaced by a new string:

If n <= size(), the function replaces the string designated by *this with a string of length n whose elements are a copy of the initial elements of the original string designated by *this.

When small string optimization is used, resizing to a smaller size may cause the string to store the characters in-place, rather than in a dynamically allocated buffer.


In C++20 standard resize is made constexpr and the above wording is gone, see string.capacity:

constexpr void resize(size_type n, charT c);

5 #Effects: Alters the value of *this as follows:

(5.1) If n <= size(), erases the last size() - n elements.

(5.2) If n > size(), appends n - size() copies of c.

like image 177
Maxim Egorushkin Avatar answered Nov 19 '22 23:11

Maxim Egorushkin


It does not guarantee validity of pointers:

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:

  • Passing as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

  • Calling non-const member functions, except operator[], at, data, front, back, begin, rbegin, end, and rend.

resize is a non const member function and is not in the list of member functions guaranteed to not invalidate references.

like image 4
eerorika Avatar answered Nov 20 '22 00:11

eerorika