Question: Consider the following test program:

```
#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::cout << sizeof(std::string("hi")) << " ";
    std::string a[10];
    std::cout << sizeof(a) << " ";
    std::vector<std::string> v(10);
    std::cout << sizeof(v) + sizeof(std::string) * v.capacity() << "\n";
}

```

Output for `libstdc++` and `libc++` respectively are:

```
8 80 104
24 240 264

```

As you can see, `libc++` takes 3 times as much memory for a simple program. How does the implementation differ that causes this memory disparity? Do I need to be concerned and how do I workaround it?

Answer: 
Here is a short program to help you explore both kinds of memory usage of `std::string`: stack and heap.

```
#include <string>
#include <new>
#include <cstdio>
#include <cstdlib>

std::size_t allocated = 0;

void* operator new (size_t sz)
{
    void* p = std::malloc(sz);
    allocated += sz;
    return p;
}

void operator delete(void* p) noexcept
{
    return std::free(p);
}

int
main()
{
    allocated = 0;
    std::string s("hi");
    std::printf("stack space = %zu, heap space = %zu, capacity = %zu\n",
     sizeof(s), allocated, s.capacity());
}

```

Using <http://melpon.org/wandbox/> it is easy to get output for different compiler/lib combinations, for example:

**gcc 4.9.1:**

```
stack space = 8, heap space = 27, capacity = 2

```

**gcc 5.0.0:**

```
stack space = 32, heap space = 0, capacity = 15

```

**clang/libc++:**

```
stack space = 24, heap space = 0, capacity = 22

```

**VS-2015:**

```
stack space = 32, heap space = 0, capacity = 15

```

(the last line is from <http://webcompiler.cloudapp.net>)

The above output also shows `capacity`, which is a measure of how many `char`s the string can hold before it has to allocate a new, larger buffer from the heap. For the gcc-5.0, libc++, and VS-2015 implementations, this is a measure of the *short string buffer*. That is, the size buffer allocated on the stack to hold short strings, thus avoiding the more expensive heap allocation.

It appears that the libc++ implementation has the smallest (stack usage) of the short-string implementations, and yet contains the largest of the short string buffers. And if you count *total* memory usage (stack + heap), libc++ has the smallest total memory usage for this 2-character string among all 4 of these implementations.

It should be noted that all of these measurements were taken on 64 bit platforms. On 32 bit, the libc++ stack usage will go down to 12, and the small string buffer goes down to 10. I don't know the behavior of the other implementations on 32 bit platforms, but you can use the above code to find out.
**Summary: It only looks like `libstdc++` uses one `char*`. In fact, it allocates more memory.**

So, you should not be concerned that Clang's `libc++` implementation is memory inefficient.

From the documentation of libstdc++ (under [Detailed Description](https://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/api/a00259.html)):

```
A string looks like this:

                                        [_Rep]
                                        _M_length
   [basic_string<char_type>]            _M_capacity
   _M_dataplus                          _M_refcount
   _M_p ---------------->               unnamed array of char_type

```

> 
> Where the \_M\_p points to the first character in the string, and you cast it to a pointer-to-\_Rep and subtract 1 to get a pointer to the header.
> 
> 
> This approach has the enormous advantage that a string object requires only one allocation. All the ugliness is confined within a single pair of inline functions, which each compile to a single add instruction: \_Rep::\_M\_data(), and string::\_M\_rep(); and the allocation function which gets a block of raw bytes and with room enough and constructs a \_Rep object at the front.
> 
> 
> The reason you want \_M\_data pointing to the character array and not the \_Rep is so that the debugger can see the string contents. (Probably we should add a non-inline member to get the \_Rep for the debugger to use, so users can check the actual string length.)
> 
> 
> 

So, it just looks like one `char*` but that is misleading in terms of memory usage.

Previously `libstdc++` basically used this layout:

```
  struct _Rep_base
  {
    size_type               _M_length;
    size_type               _M_capacity;
    _Atomic_word            _M_refcount;
  };

```

That is closer to the results from `libc++`.

`libc++` uses "short string optimization". The exact layout depends on whether `_LIBCPP_ABI_ALTERNATE_STRING_LAYOUT` is defined. If it is defined, the data pointer will be word-aligned if the string is short. For details, see the [source code](http://llvm.org/svn/llvm-project/libcxx/trunk/include/string).

Short string optimization avoids heap allocations, so it also looks more costly than `libstdc++` implementation if you only consider the parts that are allocated on the stack. `sizeof(std::string)` only shows the stack usage not the overall memory usage (stack + heap).