Skip to content

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 dogtwice. 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:

std::string quote = std::string("With great power ") + "comes great responsibility";

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

Open in Compiler Explorer ↗ Quiz this entry