Arrays and Strings
std::string_view (C++17)
Non-owning, zero-copy string reference for efficient read-only access
Interview: Performance optimization — shows understanding of ownership, views, and avoiding unnecessary copies
std::string_view (C++17)
std::string_view is a lightweight, non-owning reference to a contiguous sequence of characters. It stores just two things: a pointer to the first character and a length. It doesn't own or manage the memory it references — no allocation, no copying. The fundamental design principle: if you only need to read a string, you don't need to own it.
Why string_view Matters
Before C++17, a function accepting any string had to choose between const char* (can't handle std::string without length) and const std::string& (forces a heap allocation for string literals via implicit conversion). string_view accepts both — and any other string-like type — with zero overhead.
| Parameter Type | Accepts literal? | Accepts std::string? | Allocation? | Has Length? |
|---|---|---|---|---|
| const char* | Yes | Yes (via .c_str()) | No | No (strlen needed) |
| const string& | Yes (temporary copy) | Yes | Yes (for literals) | Yes |
| string_view | Yes | Yes | No | Yes |
The Dangling View Problem
Since string_view doesn't own its data, it becomes a dangling view if the underlying string is destroyed. This is the primary danger: storing a string_view that was constructed from a temporary std::string — the string is destroyed, but the view still points to its memory.
substr Without Allocation
string_view::substr returns another string_view — not a new string. It simply adjusts the pointer and length. This means slicing is O(1) and allocation-free, unlike std::string::substr which copies. Extremely valuable for parsing pipelines.
Interview Corner
Q: When should you use string_view vs const string& as a function parameter?
A: Use string_view when the function only reads the string and the caller may pass literals, substrings, or non-null-terminated views — no allocation needed. Use const string& when you need to call functions that require null-termination (like C APIs via .c_str()). string_view doesn't guarantee null-termination — a view into the middle of a string has no null at the end.
Q: How can string_view cause undefined behavior?
A: By outliving the string it views. Classic bug: string_view sv = std::string("hello"); — the temporary is destroyed at the end of the statement, leaving sv dangling. Or: storing a string_view in a class member initialized from a function-local string. Safe rule: only store string_view when you can guarantee the owner string outlives it.
Common Pitfalls
- Dangling view from temporary:
string_view sv = getString();wheregetString()returns astd::stringby value — the temporary is immediately destroyed. - Assuming null-termination: Passing
sv.data()to a C function expecting null-terminated strings is unsafe unless the view points to a full string (not a substring). - Storing string_view class members: If a class stores a
string_viewmember initialized from a constructor parameter'sstd::string, lifetime management is tricky. Consider storingstd::stringinstead.
Best Practices
- Use
string_viewfor all read-only string function parameters — it's the zero-overhead universal string interface. - Never store a
string_viewbeyond the scope of the string it was created from. If lifetime is uncertain, copy to astd::string. - Use the
svstring literal suffix (C++17) for string_view literals:using namespace std::string_view_literals; auto sv = "hello"sv;