65 Intermediate The Hundred
The View of a Dead String
the quote that quietly quotes someone else
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string_view quote = std::string("With great power ") + "comes great responsibility";
std::string pangram = "The quick brown fox jumps over the lazy dog";
std::cout << quote << "\n";
std::cout << pangram << "\n";
}
Run it. What are the two lines?
Answer
Typical output (GCC 11 on x86-64): The quick brown fox jumps over the lazy dog — twice.
Spider-Man never shows up. This is undefined behavior, so your run may differ.
Why¶
std::string_view looks like a value — cheap to copy, pleasant to pass, no * in sight —
but it holds only a pointer and a length into characters it does not own, and std::string
converts to one implicitly. So quote silently borrows the concatenation's temporary
buffer, which is freed at the semicolon; pangram then asks the allocator for a same-sized
block, gets that freed one back, and quote ends up viewing someone else's sentence —
reading it is undefined behavior. As a parameter a view is safe, because the caller's
string outlives the call; the hazard is entirely in storing one — a member, a container
element, a returned view. Nothing in the type system marks that borrow: GCC 11 is silent
even with -Wall -Wextra, and Clang 18, which does flag this particular initialization
under -Wdangling-gsl, goes quiet the moment the same view is stashed in a struct member or
pushed into a std::vector. Entry 64 is the same wound inflicted through c_str().
The fix¶
Own the characters outright:
Or, if you truly want a view, borrow from a named owner that outlives it:
std::string owner = std::string("With great power ") + "comes great responsibility";
std::string_view quote = owner;
Takeaway: a string_view parameter is safe; a string_view you store is a promise
about someone else's lifetime that no compiler will hold you to.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo