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: 
**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).
I haven't checked the actual implementations in source code, but I remember checking this when I was working on my C++ string library. A 24 byte string implementation is typical. If the length of the string is smaller than or equal to 16 bytes, instead of malloc'ing from the heap, it copies the string into the internal buffer of size 16 bytes. Otherwise, it mallocs and stores the memory address etc. This minor buffering actually helps in terms of running time performance.

For some compilers, there's an option to turn the internal buffer off.