为什么sizeof(string)== 32?

aga*_*gam 21 c++ string

字符串结构中导致sizeof()为32的开销是多少?

Kon*_*lph 47

大多数现代std::string实现1在一个静态大小的char数组中直接在堆栈上保存非常小的字符串,而不是使用动态堆存储.这称为小(或短)字符串优化(SSO).它允许实现避免小字符串对象的堆分配并改善引用的局部性.

此外,将有一个std::size_t成员来保存字符串大小和指向实际char存储的指针.

如何具体实现这一点有所不同,但以下几行有效:

template <typename T>
struct basic_string {
    char* begin_;
    size_t size_;
    union {
        size_t capacity_;
        char sso_buffer[16];
    };
};
Run Code Online (Sandbox Code Playgroud)

在典型架构中,sizeof (void*)= 8,这给我们的总大小为32字节.


1 "三巨头"(GCC的libstdc ++自第5版以来,Clang的libc ++和MSVC的实现)都是这样做的.其他人也可能.


Ant*_*ams 12

std::string 通常包含"小字符串优化"的缓冲区---如果字符串小于缓冲区大小,则不需要堆分配.

  • Windows编译器并不是唯一进行小字符串优化的人 (3认同)
  • 顺便说一下,我之所以提到它,是因为"通常"的范围从"我有理由相信你永远不会看到任何其他东西",到"我用过的50%或更多的实现都做到这一点".我想,这很容易被误解.这种优化和缺乏优化都不应该被认为是不寻常的. (3认同)

n.c*_*lou 7

在 g++5.2 中(例如在 g++4.9 中,它是不同的),字符串基本上定义为:

class string {
  char* bufferp;
  size_t length;
  union {
    char local_buffer[16];
    size_t capacity;
  };
};
Run Code Online (Sandbox Code Playgroud)

在普通计算机上,这总计为 32 个字节 (8+8+16)。

实际的定义当然是

typedef basic_string<char> string;
Run Code Online (Sandbox Code Playgroud)

但想法是一样的。


Mar*_*ork 5

我的猜测是:

class vector
{
    char type;
    struct Heap
    {
      char*   start;
      char*   end;
      char*   allocatedEnd;
    };
    struct Stack
    {
      char    size;
      char    data[27];
    }
    union
    {
        Stack   stackVersion;
        Heap    heapVersion;
    } version;
};
Run Code Online (Sandbox Code Playgroud)

但我敢打赌,有数百种方法可以做到这一点。