In C++, std::string is essentially a dynamic char vector wrapper. But because strings are used everywhere, copying them constantly or triggering dynamic heap allocations can degrade application speeds. Modern C++ uses memory layouts and view classes to eliminate string copy latency.
Let's look at how strings are packed, small string optimization, and string views.
Small String Optimization (SSO)
Many standard-library implementations use Small String Optimization (SSO) to keep some short characters inside the string object and avoid a dynamic allocation. SSO is an implementation detail, not a C++ guarantee.
The layout, object size, and inline capacity of std::string vary by standard library, ABI, build settings, and target. Do not encode a specific size or inline-character limit into an API or benchmark conclusion.
The SSO Union Hack
An implementation may use a union, tagged fields, or another internal representation to support SSO. Those details are deliberately not specified by C++.
When SSO is available, a short string may store characters inside the string object; a longer one may use separately allocated storage. Treat this as a potential allocation optimization, not a fixed 15-character rule or a universal zero-allocation promise.
- The Key Metaphor: SSO is like keeping your keys in your pocket (stack storage). If you only have a few keys, you keep them on your person. If you suddenly buy a massive set of tools and equipment, you cannot fit them in your pocket, so you rent a public storage locker (heap allocation) and keep the locker ticket receipt in your pocket.
Small String Optimization (SSO)
Click toggle below to view string stack allocation layouts vs dynamic heap reallocation.
SSO Stack Optimization: By packing short character lines (like "Hello") into the string object's own local stack buffer, we avoid invoking malloc() or managing dynamic buffers, saving hundreds of nanoseconds in execution time.
String Views: Zero Copy Slices
When you pass a string to a function, you must pass it by const reference to avoid a copy. But what if you want to pass a string literal "Hello" or a slice of an array? Passing them requires instantiating a temporary string, which triggers a heap allocation.
C++17 solved this by introducing std::string_view (in the <string_view> header). A string view is a non owning wrapper. It holds only two variables: a pointer to the start of the characters, and a size integer. It never allocates heap memory.
The String View Lifetime Trap
Because std::string_view does not own the memory it references, it is highly vulnerable to dangling pointers. If the underlying string object is modified or goes out of scope, the view is left pointing to dead memory: