这是一个简短的程序,可以帮助您探索两种内存使用情况std::string
:栈和堆。
#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/ http://melpon.org/wandbox/很容易获得不同编译器/库组合的输出,例如:
海湾合作委员会 4.9.1:
stack space = 8, heap space = 27, capacity = 2
海湾合作委员会 5.0.0:
stack space = 32, heap space = 0, capacity = 15
铿锵/libc++:
stack space = 24, heap space = 0, capacity = 22
VS-2015:
stack space = 32, heap space = 0, capacity = 15
(最后一行来自http://webcompiler.cloudapp.net http://webcompiler.cloudapp.net)
上面的输出还显示capacity
,这是衡量有多少char
字符串在必须从堆中分配新的、更大的缓冲区之前可以保存。对于 gcc-5.0、libc++ 和 VS-2015 实现,这是对短字符串缓冲区。也就是说,在堆栈上分配的大小缓冲区用于保存短字符串,从而避免更昂贵的堆分配。
看起来 libc++ 实现具有最小的(堆栈使用)短字符串实现,但包含最大的短字符串缓冲区。如果你算一下total内存使用量(堆栈 + 堆),在所有 4 个实现中,libc++ 对于这个 2 字符字符串的总内存使用量是最小的。
应该注意的是,所有这些测量都是在 64 位平台上进行的。在 32 位上,libc++ 堆栈使用量将下降到 12,小字符串缓冲区下降到 10。我不知道 32 位平台上其他实现的行为,但您可以使用上面的代码来了解。