What is string_view?
Categories:
Understanding std::string_view
in C++17 and Beyond

Explore std::string_view
, a non-owning reference to a string, and learn how it improves performance and safety in C++ applications by avoiding unnecessary copies.
Before C++17, handling string data often involved either passing const std::string&
or const char*
to functions. While const std::string&
avoids copies, it still implies ownership or potential heap allocation. const char*
is lightweight but lacks length information, making it prone to errors and requiring null termination. std::string_view
, introduced in C++17 (and available earlier via the Fundamentals TS), addresses these issues by providing a lightweight, non-owning reference to a sequence of characters. It's essentially a pointer to the beginning of a character sequence and its length, without managing the underlying memory.
What is std::string_view
?
std::string_view
is a class template that provides a read-only view into an existing character sequence. It does not own the characters it refers to; it merely points to them. This means that constructing a string_view
from an std::string
or a C-style string (const char*
) does not involve any memory allocation or copying of the character data. It's a 'view' into the data, much like a pointer and a size. This characteristic makes it incredibly efficient for functions that only need to read string data without modifying it.
classDiagram class std::string { - char* data - size_t length - size_t capacity + std::string(const char*) + ~std::string() } class std::string_view { - const char* ptr - size_t len + std::string_view(const char*, size_t) + std::string_view(const std::string&) } std::string <.. std::string_view : views
Relationship between std::string
and std::string_view
Key Benefits and Use Cases
The primary advantage of std::string_view
is performance. By avoiding copies, it reduces memory allocations and CPU cycles, especially when dealing with large strings or frequent string manipulations. It's ideal for function parameters where the function only needs to read the string content. For example, a logging function or a parser that extracts substrings can greatly benefit from using string_view
.
#include <iostream>
#include <string>
#include <string_view>
void process_string(std::string_view sv) {
std::cout << "Processing: '" << sv << "' (length: " << sv.length() << ")\n";
}
int main() {
std::string s = "Hello, world!";
const char* c_str = "C-style string";
process_string(s); // No copy from std::string
process_string(c_str); // No copy from const char*
process_string("Literal string"); // No copy from string literal
// Substring operations are also views
std::string_view sub_sv = s.substr(0, 5);
process_string(sub_sv); // Still no copy
return 0;
}
Demonstrating std::string_view
with various string types
std::string_view
for input parameters that are read-only strings. This allows callers to pass std::string
, const char*
, or string literals without incurring conversion or copy costs.Important Considerations and Pitfalls
While std::string_view
offers significant benefits, its non-owning nature introduces a critical caveat: dangling views. Since string_view
does not manage the lifetime of the underlying character data, it's crucial to ensure that the data outlives the string_view
itself. If the underlying string is destroyed or goes out of scope while the string_view
still exists, accessing the string_view
will result in undefined behavior. This is similar to the dangers of dangling pointers.
flowchart TD A[Create std::string] --> B{Create std::string_view from A} B --> C[Use std::string_view] C --> D{std::string A goes out of scope?} D -- Yes --> E[std::string_view becomes dangling!] D -- No --> F[std::string_view remains valid]
Lifecycle of std::string_view
and potential dangling issues
#include <iostream>
#include <string>
#include <string_view>
std::string_view get_temporary_view() {
std::string temp_str = "Temporary data";
// DANGER: temp_str will be destroyed when this function returns
return temp_str; // Returns a dangling string_view
}
int main() {
std::string_view dangling_sv = get_temporary_view();
// Accessing dangling_sv here is UNDEFINED BEHAVIOR!
// std::cout << dangling_sv << std::endl; // CRASH or garbage output
std::string_view valid_sv;
{
std::string s = "Valid data";
valid_sv = s; // valid_sv is valid within this scope
std::cout << "Inside scope: " << valid_sv << std::endl;
} // 's' is destroyed here
// std::cout << "Outside scope: " << valid_sv << std::endl; // DANGER: dangling_sv here too!
return 0;
}
Example of dangling std::string_view
leading to undefined behavior
std::string_view
that refers to a local variable or temporary object from a function. Ensure the lifetime of the underlying character data always exceeds the lifetime of any string_view
referring to it.