如果 new_size 不大于旧的,C++ 标准是否保证 std::string::resize(new_size) 不会导致分配?

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

如果 new_size 不大于旧的,C++ 标准是否保证 std::string::resize(new_size) 不会导致分配?

首先请注意,标准通常设定要求而不是保证。

如果 resize 参数小于其当前 size(),则不需要

std::basic_string::resize 不重新分配字符串。事实上,C++17标准说当前字符串被新字符串替换:

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.

使用小字符串优化时,调整为较小的大小可能会导致字符串就地存储字符,而不是在动态分配的缓冲区中。


在C++20标准中resize变成了constexpr上面的写法没有了,见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.

它不保证指针的有效性:

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 是非 const 成员函数,不在保证不会使引用无效的成员函数列表中。