C++ std::字符串,没有空闲存储内存分配

C++ std::字符串,没有空闲存储内存分配,c++,c++11,memory-management,stdstring,C++,C++11,Memory Management,Stdstring,我有一个非常类似的问题 但我认为值得再问一次 我想要一个std::string,本地存储溢出到免费存储中std::basic_string提供了一个分配器作为模板参数,因此似乎要做的事情是编写一个带有本地存储的分配器,并使用它来参数化basic_string,如下所示: std::basic_string< char, std::char_traits<char>, inline_allocator<char, 10> > x("test"); s

我有一个非常类似的问题

但我认为值得再问一次

我想要一个
std::string
,本地存储溢出到免费存储中
std::basic_string
提供了一个分配器作为模板参数,因此似乎要做的事情是编写一个带有本地存储的分配器,并使用它来参数化
basic_string
,如下所示:

std::basic_string<
char, 
std::char_traits<char>, 
inline_allocator<char, 10> 
> 
x("test");
std::基本字符串<
烧焦
性病:性格特征,
内联分配程序
> 
x(“测试”);
我试图编写一个
内联\u分配器
类,该类的工作方式与您期望的一样:它保留10个字节用于存储,如果
基本\u字符串
需要超过10个字节,那么它将调用
::operator new()
。我无法让它工作。在执行上述代码行的过程中,我的GCC4.5标准字符串库调用了
inline_分配器的复制构造函数4次。我不清楚是否有一种合理的方法来为
内联\u分配器
编写复制构造函数

在另一个StackOverflow线程中,Eric Melski提供了Chromium中一个类的链接:

这很有趣,但它不是std::string的替代品,因为它将
std::basic_字符串
包装在一个容器中,因此您必须调用一个重载的
操作符->()
来获取
std::basic_字符串

我找不到其他解决这个问题的办法。难道没有好的解决办法吗?如果这是真的,那么
std::basic_string
std::allocator
概念是否存在严重缺陷?我的意思是,这似乎是
std::basic_string
std::allocator
的一个非常基本和简单的用例。我假设
std::allocator
概念主要是为池设计的,但我认为它也应该涵盖这一点

似乎C++0x中的右值引用移动语义可能使编写
内联\u分配器
成为可能,前提是重新编写字符串库,以便
基本\u字符串
使用其分配器的移动构造函数而不是复制构造函数。有人知道这一结果的前景如何吗


我的应用程序每秒需要构造一百万个细小的ASCII字符串,因此我最终基于
Boost.Array
,编写了自己的固定长度字符串类,它工作得很好,但这仍然困扰着我。

我相信Chromium的代码只是把东西包装成了一个漂亮的外壳。但是您可以在不使用铬包装容器的情况下获得相同的效果

因为分配器对象经常被复制,所以它需要保存一个指向内存的引用或指针。因此,您需要做的是创建存储缓冲区,创建分配器对象,然后使用分配器调用std::string构造函数

这将比使用包装器类更加冗长,但应该得到相同的效果


.

这通常是不必要的。它被称为“短字符串优化”,大多数
std::string
的实现已经包含了它。可能很难找到,但它通常都在那里

举个例子,这里是MinGW的一部分的相关
sso\u string\u base.h

  enum { _S_local_capacity = 15 };

  union
  {
_CharT           _M_local_data[_S_local_capacity + 1];
size_type        _M_allocated_capacity;
  };
\u M_local_data
成员是相关的一个成员,它可以存储(最多)15个字符(加上NUL终止符),而无需在堆上分配任何空间

如果内存可用,VC++附带的Dinkumware库会为20个字符分配空间,尽管我已经有一段时间没有看过了,所以我不能保证(而且跟踪标题中的大部分内容往往很痛苦,所以如果可以的话,我宁愿避免看)


无论如何,我会给你一个很好的机会,你已经参与了这个众所周知的过早优化。< /P> < P> Andrei Alexandrescu,C++程序员,他写了一篇“现代C++设计”,曾经写了一篇伟大的文章,关于用可定制的存储系统构建不同的字符串实现。他的文章()描述了如何实现上面描述的,作为一个更通用的系统的特例,该系统可以处理各种智能内存分配需求。这篇文章并没有太多关于std::string的内容,更多地关注于一个完全定制的string类,但您可能希望研究一下它,因为在实现中有一些真正的宝石。

C++2011确实会在这方面帮助您:)

事实上,C++03中的
分配器
概念已经失效。其中一个要求是
A
类型的分配器应该能够从
A
类型的任何其他分配器中释放内存。。。不幸的是,这一要求与每个连接到自己池的有状态分配器也不一致


Howard Hinnant(谁管理C++的STL子群,并为C++ 0x从头开始实现一个新的STL),您可以从中得到启发。

作为过去与自定义分配者搏斗的人,我非常感兴趣的是在这个主题上发言。+ 1的“免费商店”。哦,因为这是一个好问题。链接到的是关于基本字符串存储的精彩讨论。不过,我仍然想知道,在我的问题中是否有可能编写
inline\u分配器
类。简单看一下Alexandresu的文章并不能告诉我答案,我将不得不花一些时间来研究它。Chromium的stack_容器.h的链接已经失效。这里有一个更新的:VC++为SSO分配了16个字节,在我看来,这太小了,通常不太有用,因为
std::wstring
在Windows代码中比
std::string
更常用,并且在
std::wstring
中只允许8个字符(如果经常使用
.c_str()
,则为7个字符).标头不属于MinGW库扩展(不是std::string的一部分)吗