GCC中的std :: string实现及其短字符串的内存开销

时间:2011-02-20 17:28:13

标签: c++ string compiler-construction memory-management

我目前正在开发一个低内存平台的应用程序,该平台需要std :: set的许多短字符串(> 100,000个字符串,每个字符串4-16个字符)。我最近将这个集合从std :: string转换为const char *以节省内存,我想知道我是否真的避免了每个字符串的所有开销。

我尝试使用以下内容:

std::string sizeTest = "testString";
std::cout << sizeof(sizeTest) << " bytes";

但它只给了我一个4字节的输出,表明该字符串包含一个指针。我很清楚字符串在内部将它们的数据存储在char *中,但我认为字符串类会有额外的开销。

std :: string的GCC实现是否会产生比sizeof(std :: string)更多的开销?更重要的是,这个数据集的大小是否显着?

以下是我平台上相关类型的大小(它是32位,每字节8位):

char:1个字节
void *:4个字节
char *:4个字节
std :: string:4个字节

4 个答案:

答案 0 :(得分:13)

好吧,至少GCC 4.4.5,这就是我对此有用的东西 机器,std::stringstd::basic_string<char>的典型代码,并且 basic_string定义于 /usr/include/c++/4.4.5/bits/basic_string.h。有很多 在该文件中的间接,但它归结为非空 std::string存储指向其中一个的指针:

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

通过实际的字符串数据跟踪内存。所以std::string是 每个字符串至少要有三个字句,加上 比capacity更高`length的任何开销(可能是。{ 不是,取决于你如何构建你的字符串 - 你可以检查 询问capacity()方法。

你的内存分配器也会产生开销 很多小额拨款;我不知道GCC用于C ++的是什么,但是 假设它类似于它用于C的dlmalloc分配器,那 可以是每个分配至少两个单词,加上一些空格来对齐 大小为至少8个字节的倍数。

答案 1 :(得分:8)

我猜你是在32位,每字节8位平台上。我还要猜测,至少在您使用的gcc版本上,他们正在使用std :: string的引用计数实现。您看到的4字节大小是指向包含引用计数和字符串数据(以及任何分配器状态,如果适用)的结构的指针。

在gcc的这种设计中,唯一的“短”字符串的大小为== 0,在这种情况下,它可以与每个其他空字符串共享一个表示。否则你会得到一个refcounted COW字符串。

要自己调查一下,编写一个分配器来跟踪它分配和释放的内存量,以及多少次。使用此分配器来调查您感兴趣的容器的实现。

答案 2 :(得分:3)

如果保证“&gt; 100,000个字符串,每个字符串4-16个字符”,则不要使用std :: string。相反,编写自己的ShortString类。有趣的是“sizeof(std :: string)== 4”,这怎么可能?什么是sizeof(char)和sizeof(void *)?

答案 3 :(得分:2)

我已经对std :: string开销进行了一些比较。一般来说它大约是48个字节!看看我博客上的文章: http://jovislab.com/blog/?p=76