Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to append std::string to itself?

Tags:

c++

stl

Considering a code like this:

std::string str = "abcdef";
const size_t num = 50;

const size_t baselen = str.length();
while (str.length() < num)
    str.append(str, 0, baselen);

Is it safe to call std::basic_string<T>::append() on itself like this? Cannot the source memory get invalidated by enlarging before the copy operation?

I could not find anything in the standard specific to that method. It says the above is equivalent to str.append(str.data(), baselen), which I think might not be entirely safe unless there is another detection of such cases inside append(const char*, size_t).

I checked a few implementations and they seemed safe one way or another, but my question is if this behavior is guaranteed. E.g. "Appending std::vector to itself, undefined behavior?" says it's not for std::vector.

like image 498
Yirkha Avatar asked Sep 08 '25 16:09

Yirkha


1 Answers

According to §21.4.6.2/§21.4.6.3:

The function [basic_string& append(const charT* s, size_type n);] replaces the string controlled by *this with a string of length size() + n whose first size() elements are a copy of the original string controlled by *this and whose remaining elements are a copy of the initial n elements of s.

Note: This applies to every append call, as every append can be implemented in terms of append(const charT*, size_type), as defined by the standard (§21.4.6.2/§21.4.6.3).

So basically, append makes a copy of str (let's call the copy strtemp), appends n characters of str2 to strtemp, and then replaces str with strtemp.

For the case that str2 is str, nothing changes, as the string is enlarged when the temporary copy is assigned, not before.

Even though it is not explicitly stated in the standard, it is guaranteed (if the implementation is exactly as stated in the standard) by the definition of std::basic_string<T>::append.

Thus, this is not undefined behavior.

like image 136
Rakete1111 Avatar answered Sep 10 '25 05:09

Rakete1111