C++ 如何使用glibc';什么是字符串实现?

C++ 如何使用glibc';什么是字符串实现?,c++,memory,stack,heap,stdstring,C++,Memory,Stack,Heap,Stdstring,我的理解是,上面的代码使用默认的分配器来调用new。因此,即使std::string foo是在堆栈上分配的,foo内部的缓冲区也是在堆上分配的 我怎样才能创建一个完全在堆栈上分配的字符串呢?我怀疑做这样的事情很难,我想知道你为什么要这么做?要完全在堆栈上分配内容,编译器需要在编译时知道内容的确切大小——在您的示例中,它不仅需要知道std::string元数据的大小,还需要知道字符串数据本身的大小。这不是很灵活,您可能需要不同的字符串类型,这取决于您想要包含在其中的字符串数据的大小-并不是说这是

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


我怎样才能创建一个完全在堆栈上分配的字符串呢?

我怀疑做这样的事情很难,我想知道你为什么要这么做?要完全在堆栈上分配内容,编译器需要在编译时知道内容的确切大小——在您的示例中,它不仅需要知道
std::string
元数据的大小,还需要知道字符串数据本身的大小。这不是很灵活,您可能需要不同的字符串类型,这取决于您想要包含在其中的字符串数据的大小-并不是说这是不可能做到的,只是这会使事情变得有点复杂。

  • string将始终使用new/delete管理其内部存储
  • 不确定您的问题为什么包含glibc的字符串实现。C++标准库的字符串实现与GLIMBC无关。
  • 在堆栈上存储字符串的唯一方法是在堆栈上使用C字符数组(如Shhnap所述)。但这可能不是你想要的:-)

    • 问题在于
      std::basic_string
      有一个用于分配器的模板参数。但是
      std::string
      不是模板,没有参数

      因此,原则上,您可以将
      std::basic_string
      的实例化与使用堆栈内存的分配器一起使用,但它不会是
      std::string
      。特别是,您将无法获得运行时多态性,并且您无法将结果对象传递到需要
      std::string

      的函数中,您无法这样做。除了

      std::string

      int main(void)
      {
         std::string foo("foo");
      }
      
      std::基本字符串
      
      可以想象,您可以定义一个用于内存管理的分配器类。只有当分配器本身以及直接或间接调用它的
      basic_string
      方法都是
      inline
      时,这才有效。使用此分配器创建的
      basic_string
      对象不会
      std::string
      ,但其行为(大部分)与之类似。然而,这将是一个相当多的工作,收益有限。具体来说,使用此类从函数返回值将是一种职业限制


      我不知道为什么你或其他人会想这样做。

      我最近想自己做,发现下面的代码很有启发性:

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

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

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

      一些人评论说,使用基于堆栈的分配的字符串将不会是
      std::string
      ,好像这会以某种方式降低其效用。是的,您不能互换使用这两个函数,因此无法将
      stackstring
      传递给需要
      std::string
      的函数。但是(如果你做得对的话),你将能够在你的
      stackstring
      上使用你现在在
      std::string
      上使用的所有相同的成员函数,比如
      find\u first\u of()
      append()
      ,等等。
      begin()
      end()
      仍然可以正常工作,因此你将能够使用许多STL算法。当然,严格意义上讲,它不是std::string,但在实际意义上它仍然是一个“string”,并且仍然非常有用。

      关于第一点,标准中真的有什么东西吗。。好吧,内部实现可以自由地进行小字符串大小的优化,而不涉及堆。Majkara是正确的,小字符串(std::string定义的是接口而不是实现。我专门询问glibc实现,因为它是我正在使用的。如果我使用的是MSVC实现,我不会问这个问题。幸运的是,我得到了一个独立于实现的答案。@poindexter glibc没有std::striNG实现。它在GCC中的LIbSTDC++中。@ Majkara Tito,一些编译器的实现做小字符串大小优化并不意味着你可以编写(可移植)C++,其中你的字符串不是HEP分配的。“根据要包含在其中的字符串数据的大小,您可能需要不同的字符串类型”。欢迎使用Symbian!我不确定这将如何工作?您建议分配器如何修改其调用者的堆栈帧?只需执行alloca()因为当分配器返回指针时,或者当std::string的con
      std::basic_string<class CharType, 
                        class Traits=char_traits<CharType>, 
                        class Allocator=allocator<CharType> >