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

Whe*_*evo 20 c++ compiler-construction string memory-management

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

我尝试使用以下内容:

std::string sizeTest = "testString";
std::cout << sizeof(sizeTest) << " bytes";
Run Code Online (Sandbox Code Playgroud)

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

std :: string的GCC实现是否比sizeof(std :: string)指示的更多开销?更重要的是,这个数据集的重要性是否显着?

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

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

nel*_*age 13

好吧,至少GCC 4.4.5,这是我在这台机器上得到的便利,std::string是一个typdef std::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;
  };
Run Code Online (Sandbox Code Playgroud)

在实际的字符串数据中跟随内存.因此,std::string将不得不为每串开销至少三个词,加上任何开销针对具有高capacity`length(可能不是,这取决于你如何构建你的字符串-你可以通过询问检查capacity()方法).

你的内存分配器也会有大量的小额分配开销; 我不知道GCC使用什么C++,但假设它类似于dlmalloc它用于C 的分配器,每个分配至少可以有两个字,加上一些空间可以将大小与至少8个字节的倍数对齐.

  • 许多实现使用小缓冲区优化来不对少于 3-7 个字符的字符串进行分配,GCC 不这样做吗? (2认同)

How*_*ant 8

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

在这个gcc的设计中,唯一的"短"字符串的大小为== 0,在这种情况下,它可以与其他每个空字符串共享一个表示.否则,您将获得一个refcounted COW字符串.

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