C++ 为什么 sizeof(string) == 32?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3770781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is sizeof(string) == 32?
提问by agam
What is the overhead in the string structure that causes sizeof() to be 32 ?
导致 sizeof() 为 32 的字符串结构的开销是多少?
回答by Konrad Rudolph
Most modern std::string
implementations1save very small strings directly on the stack in a statically sized char
array instead of using dynamic heap storage. This is known as Small (or Short) String Optimisation(SSO). It allows implementations to avoid heap allocations for small string objects and improves locality of reference.
大多数现代std::string
实现1将非常小的字符串直接保存在静态大小的char
数组中的堆栈上,而不是使用动态堆存储。这称为小(或短)字符串优化(SSO)。它允许实现避免小字符串对象的堆分配并提高引用的局部性。
Furthermore, there will be a std::size_t
member to save the strings size and a pointer to the actual char
storage.
此外,将有一个std::size_t
成员来保存字符串大小和一个指向实际char
存储的指针。
How this is specifically implemented differs but something along the following lines works:
具体实现方式有所不同,但以下几行是有效的:
template <typename T>
struct basic_string {
char* begin_;
size_t size_;
union {
size_t capacity_;
char sso_buffer[16];
};
};
On typical architectures where sizeof (void*)
= 8, this gives us a total size of 32 bytes.
在sizeof (void*)
= 8 的典型架构上,这使我们的总大小为 32 字节。
1The “big three” (GCC's libstdc++ since version 5, Clang's libc++ and MSVC's implementation) all do it. Others may too.
1“三巨头”(GCC 的 libstdc++ 自第 5 版起,Clang 的 libc++ 和 MSVC 的实现)都做到了。其他人也可能。
回答by Anthony Williams
std::string
typically contains a buffer for the "small string optimization" --- if the string is less than the buffer size then no heap allocation is required.
std::string
通常包含用于“小字符串优化”的缓冲区——如果字符串小于缓冲区大小,则不需要分配堆。
回答by Martin York
My guess is:
我的猜测是:
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;
};
But I bet there are hundreds of ways of doing it.
但我敢打赌,有数百种方法可以做到这一点。
回答by André Caron
It is library dependent. You shouldn't rely on the size of std::string
objects because it is likely to change in different environments (obviously between different standard library vendors, but also between different versions of the same library).
它依赖于库。您不应该依赖std::string
对象的大小,因为它可能会在不同的环境中发生变化(显然在不同的标准库供应商之间,以及在同一库的不同版本之间)。
Keep in mind that std::string
implementations are written by people who have optimized for a variety of use cases, typically leading to 2 internal representations, one for short strings (small internal buffer) and one for long strings (heap-allocated external buffer). The overhead is associated to holding both of these inside each std::string
object.
请记住,std::string
实现是由针对各种用例进行优化的人编写的,通常会导致 2 种内部表示,一种用于短字符串(小型内部缓冲区),另一种用于长字符串(堆分配的外部缓冲区)。开销与在每个std::string
对象中保存这两个相关联。
回答by n.caillou
In g++5.2 (in e.g. g++4.9, it is different) a string is basically defined as :
在 g++5.2 中(例如在 g++4.9 中,它是不同的)一个字符串基本上定义为:
class string {
char* bufferp;
size_t length;
union {
char local_buffer[16];
size_t capacity;
};
};
On an ordinary computer this adds up to 32 bytes (8+8+16).
在普通计算机上,这加起来为 32 个字节(8+8+16)。
The actual definition is of course
实际的定义当然是
typedef basic_string<char> string;
but the idea is the same.
但想法是一样的。
回答by Jive Dadson
Q: Why is a dog yellow? A: It's not necessarily.
问:为什么狗是黄色的?答:不一定。
The size of a (an?) std::string object is implementation-dependent. I just checked MS VC++ 2010. It does indeed use 32 bytes for std::string. There is a 16 byte union that contains either the text of the string, if it will fit, or a pointer to heap storage for longer strings. If the implementers had chosen to keep 18 byte strings in the string object rather than on the heap, the size would be 34 bytes. The other 16 bytes comprise overhead, containing such things as the length of the string and the amount of memory currently allocated for the string.
(an?) std::string 对象的大小取决于实现。我刚刚检查了 MS VC++ 2010。它确实为 std::string 使用了 32 个字节。有一个 16 字节的联合体,它包含字符串的文本(如果它适合的话),或者一个指向长字符串的堆存储的指针。如果实现者选择在字符串对象中而不是在堆中保留 18 字节的字符串,则大小将为 34 字节。其他 16 个字节包括开销,包含诸如字符串长度和当前为字符串分配的内存量等内容。
A different implementation might always allocate memory from the heap. Such an implementation would undoubtedly require less memory for the string object.
不同的实现可能总是从堆中分配内存。这样的实现无疑会为字符串对象需要更少的内存。