Search code examples
c++stringperformancememory-managementstandards

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?


#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?


Solution

  • 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.