如何使用glibc的字符串实现在堆栈上分配std :: string?

poi*_*ter 17 c++ memory heap stack stdstring

int main(void)
{
   std::string foo("foo");
}
Run Code Online (Sandbox Code Playgroud)

我的理解是上面的代码使用默认的allocator来调用new.因此,即使在堆栈上分配了std :: string foo,foo中的内部缓冲区也会在堆上分配.

如何创建完全在堆栈上分配的字符串?

Eri*_*ski 22

我最近想自己做这件事并发现以下代码:

Chronium的stack_container.h

它定义了一个新的std::allocator,它可以为STL容器的初始存储分配提供基于堆栈的分配.我找到了一种不同的方法来解决我的特定问题,所以我实际上并没有自己使用代码,但也许它对你有用.请务必阅读代码中有关使用和警告的注释.

对于那些质疑这样做的实用性和理智性的人,请考虑:

  • 通常,您事先知道您的字符串具有合理的最大大小.例如,如果字符串将存储十进制格式的32位整数,则您知道这样做不需要超过11个字符.在这种情况下,不需要能够动态增长到无限大小的字符串.
  • 在许多情况下,从堆栈分配比从堆分配更快.
  • 如果频繁地创建和销毁字符串(假设它是常用实用程序函数中的局部变量),则从堆栈而不是堆中分配将避免碎片导致堆分配器中的流失.对于使用大量内存的应用程序,这可能会改变游戏规则.

有些人评论说,使用基于堆栈的分配的字符串不会std::string像某种方式那样削弱它的效用.没错,你不能互换地使用这两个,所以你将无法将你stackstring的功能传递给期望的std::string.但是(如果你这样做是正确的),你就可以用你的所有相同的成员函数stackstring,你现在上使用std::string,如find_first_of(),append()begin(),并end()仍将正常工作,那么你就可以使用许多STL算法.当然,它不会std::string在最严格的意义上,但在实际意义上它仍然是一个"字符串",它仍然是非常有用的.

  • 这对glibc的std :: basic_string不起作用,它调用Allocator的默认构造函数,StackAllocator不支持. (2认同)
  • 该网址不再有效.以下是更新的:[http://src.chromium.org/viewvc/chrome/trunk/src/base/containers/stack_container.h?view=markup](http://src.chromium.org/viewvc/铬/中继/ SRC /碱/容器/ stack_container.h?视图=标记) (2认同)

Ste*_*sop 11

问题是std::basic_string具有分配器的模板参数.但std::string它不是模板,也没有参数.

所以,原则上你可以使用一个std::basic_string在堆栈上使用内存的分配器的实例化,但它不会是一个std::string.特别是,您不会获得运行时多态性,并且您无法将结果对象传递给期望a的函数std::string.