int main(void)
{
std::string foo("foo");
}
我的理解是上面的代码使用默认的allocator来调用new。因此,即使在堆栈上分配了std :: string foo,foo中的内部缓冲区也会在堆上分配。
如何创建完全在堆栈上分配的字符串?
答案 0 :(得分:21)
我最近想自己做这件事并发现以下代码:
它定义了一个新的std::allocator
,它可以为STL容器的初始存储分配提供基于堆栈的分配。我找到了一种不同的方法来解决我的特定问题,所以我实际上并没有自己使用代码,但也许它对你有用。请务必阅读代码中有关使用和警告的注释。
对于那些质疑这样做的实用性和理智性的人,请考虑:
有些人评论说,使用基于堆栈的分配的字符串不会是std::string
,就好像这会以某种方式降低其效用。是的,您不能互换使用这两者,因此您无法将stackstring
传递给期望std::string
的函数。但是(如果你做对了),你将可以使用stackstring
上std::string
上find_first_of()
使用的所有相同成员函数,例如append()
,begin()
等等end()
和std::string
仍然可以正常工作,因此您将能够使用许多STL算法。当然,从最严格的意义上说它不会是{{1}},但在实际意义上它仍然是一个“字符串”,它仍然会非常有用。
答案 1 :(得分:11)
问题是std::basic_string
有一个分配器的模板参数。但std::string
不是模板,也没有参数。
因此,您原则上可以使用std::basic_string
的实例化,其中分配器使用堆栈上的内存,但它不是std::string
。特别是,您不会获得运行时多态性,并且无法将生成的对象传递给期望std::string
的函数。
答案 2 :(得分:4)
你做不到。除了...
std::string
是
std::basic_string<class CharType,
class Traits=char_traits<CharType>,
class Allocator=allocator<CharType> >
您可以想象定义一个使用alloca进行内存管理的Allocator类。只有当Allocator本身以及直接或间接调用它的basic_string
方法都是inline
时,这才有效。使用此分配器创建的basic_string
对象不会 一个std::string
,但它会(大部分)表现得像它一样。但是,这对于有限的收益来说是相当多的工作。具体来说,使用此类从函数返回值将是一个职业限制的举措。
我不知道为什么你或其他任何人想要这样做。
答案 3 :(得分:0)
我怀疑做这样的事情很难做到,我想知道你为什么要这样做?要在堆栈上完全分配一些东西,编译器需要在编译时知道事物的确切大小 - 在您的示例中,它不仅需要知道std::string
元数据的大小,还需要知道大小字符串数据本身。这不是太灵活,你可能需要不同的字符串类型,这取决于你想要包含在其中的字符串数据的大小 - 而不是不可能做到,只是它会使事情变得复杂。
答案 4 :(得分:-3)