为未初始化的 std::string 变量分配了多少内存?

And*_*Kay 1 c++ memory string

如果我声明一个 std::string 类型的变量但不初始化它,则分配多少内存?我知道,如果我将其初始化为“hello”,那么将为每个字符保留一个字节,加上一个空字符,总共 6 个字节。字符串类中是否定义了默认长度?(我尝试在字符串头文件中查找实际定义,但不知道在哪里找到它)

Bri*_*ian 5

这是未指定的。不同的实现可能会在默认构造时分配不同数量的内存,并且不需要实现告诉您具体有多少内存。然而,我相信现在最常见的是std::string采用短字符串优化,在这种优化下,默认构造的std::string除了类本身的大小之外根本不需要分配任何内存std::string。有关详细信息,请参阅std::string 上下文中首字母缩略词 SSO 的含义。请注意,这sizeof(std::string)也是未指定的。


Asu*_*Asu 5

根据 C++ 标准,这是未指定的,因此标准库实现可以在这里自由地执行任何操作。在实践中...

  1. std::string大多数实现在初始化空对象时不会动态分配内存,但并不要求它们不这样做

  2. 至于sizeof(std::string)桌面平台上的典型值范围是 12 到 32 字节。这是基于使用 Compiler Explorer 完成的一些测试(如果您想测试其他平台,请链接到测试):

  • gcc/Linux/x86-64/libstdc++:32 字节
  • gcc/Linux/x86/libstdc++:24 字节
  • clang / Linux / x86-64 / libc++ (注意:不是 libstdc++!):24 字节
  • clang / Linux / x86 / libc ++:12字节
  • msvc / Windows / x86-64 / VC运行时:32字节
  • msvc / Windows / x86 / VC运行时:24字节
  • gcc/Linux/ARM64/libstdc++:32 字节
  • gcc/Linux/ARM(32 位)/libstdc++:24 字节
  • msvc / Windows / ARM64 / VC 运行时:32 字节(注意:在 CE 上输出为十六进制)

这里起作用的一个重要因素是广泛使用的短字符串优化。SSO 允许短字符串适合std::string对象本身,从而绕过动态分配。
SSO 缓冲区有多大取决于每个实现如何决定平衡这种权衡。例如,这就是同一平台之间和同一平台上的sizeof差异的主要原因。 @Brian 的回答和一些参考问题中进一步讨论了 SSO 的工作原理以及它为何有用。std::stringlibstdc++libc++