Can I change a std::string, which has been assigned to a std::string_view

697 Views Asked by At

I just knew that C++17 introduced std::string_view. It doesn't hold any string, instead, it points to a string. If so, I'm confused by the case below:

std::string str = "abc";
std::string_view strV = str;
std::cout << strV << std::endl;
str = "1";
std::cout << strV << std::endl;

I just tried the piece of code on some c++17 compiler online, here is the output:

abc
1c

Obviously, 1c is not what I expected.

So does it mean that we shouldn't change the string which has been assigned to a std::string_view?

3

There are 3 best solutions below

3
Deduplicator On BEST ANSWER

In general, you shouldn't, as it is fragile.
Anyway:

You may change the data behind a reference (a std::string_view is a reference to a string-segment, not to a string like std::string, consisting of start and length), just be aware that you did and how you did it.
Though refrain from deallocating it, using dangling references is bad.

std::string doesn't reallocate if the new value fits the current capacity and there is no move-assignment, or both are in SBO-mode.
In your example, all three are true.

The only problem is that the data beyond the string-terminator is indeterminate after the assignment, though it is not explicitly overwritten, thus staying c for efficiency.

2
maxbachmann On

A string_view stores a pointer to the start of the string and the length of the string. Replacing the text stored by the string invalidates both of them, since this might lead to a different length and/or a different storage location.

So yes changing the string invalidates the string_view.

0
Marek R On

std::string_view is just fancy form of const reference to buffer containing characters. This buffer can be manged by std::string or can be string literal or some array of char.

As a result use of std::string_view must not extend beyond of lifetime of this buffer. In your example buffer was modified before string view was used leading to undefined behavior.

Now since most compilers are implementing Small String Optimization, your example didn't crash. In more general cases this code will fail miserably.

Note that std::string_view was introduced mainly to more effectively parse some data in long strings which are not modified.