【问题标题】:How are C++ strings stored? [duplicate]C++ 字符串是如何存储的? [复制]
【发布时间】:2012-02-26 07:09:28
【问题描述】:

可能重复:
std::string and its automatic memory resizing

我只是好奇,字符串是如何存储在内存中的?例如,当我这样做时:

string testString = "asd";

它分配了 4 个字节,对吗? a + s + d + \0

但后来,当我想为这个字符串分配一些新文本时,它可以工作,但我不明白如何。例如我这样做:

testString = "123456789"

现在它应该是 10 个字节长。但是如果这样的字符串没有空间怎么办?假设从字符串开头的第 5+6 个字节被其他 2 个字符占用。 CPU如何处理它?它在内存中找到适合该字符串的全新位置?

【问题讨论】:

  • 可能不是完全重复,原来的问题已经知道内存是由字符串动态分配的,我不确定这里是不是这样。无论如何,我不会投票重新开放。

标签: c++ string memory


【解决方案1】:

这取决于实现,但一般的想法是字符串类将包含一个指向存储字符串实际内容的内存区域的指针。两种常见的实现是存储 3 个指针(分配区域和数据的开始、数据结束、分配区域的结束)或指针(分配区域和数据的开始)和两个整数(字符串中的字符数和分配的数字节)。

当新数据附加到字符串时,如果它适合分配的区域,它将被写入,并且数据指针的大小/结尾将相应地更新。如果数据不适合该区域,则将创建一个新缓冲区并复制数据。

还请注意,许多实现都对小字符串进行了优化,其中字符串类确实包含一个小缓冲区。如果字符串的内容适合缓冲区,则不会动态分配内存,只使用本地缓冲区。

【讨论】:

  • 那么 3 个指针是 24 字节(在 64 位拱上)。如果您只是使用指针的空间作为缓冲区来覆盖指针,那么这是一个合理大小的字符串。
  • @LokiAstari:您必须在某处添加一个额外的标志来识别内存是否用作缓冲区。但一个公平的假设是,将指针重用于小型缓冲区优化是便宜
【解决方案2】:

string 不是像char * 这样的简单数据类型。它是一个,它的实现细节不一定是可见的。

除其他外,string 包括一个计数器,用于跟踪它的实际大小。

char[] test = "asd";       // allocates exactly 4 bytes
string testString = "asd"; // who knows?

testString = "longer";     // allocates more if necessary

建议:编写一个简单的程序并使用调试器逐步完成。检查string,看看私有成员如何随着值的变化而变化。

【讨论】:

    【解决方案3】:

    string 是一个对象,而不仅仅是一些内存位置。它根据需要动态分配内存。

    = 运算符重载;当您说testString = "123456789"; 时,正在调用一个方法并处理您传入的const char *

    【讨论】:

    • 如果我没记错的话,std::string 不是对象。
    • 所以字符串中的字符不必在内存中逐字节排序(如普通数组),但它们可以存储在某个随机位置?
    • @jrok:看来你搞错了......除非你真的是说std::string是一种类型(模板的实例化),对象是从它实例化的......
    • @user1145902:它们像数组一样存储在内存中,但该内存不是在堆栈中分配(或字符串对象所在的任何位置),而是在动态分配的缓冲区中。
    • @DavidRodríguez-dribeas 是的,我是这个意思。
    【解决方案4】:

    它以大小存储。如果你存储一个新字符串,它会选择性地释放现有内存并分配新内存以应对大小的变化。

    而且它并不一定会在你第一次为它分配一个 4 字节的字符串时分配 4 个字节。它可能会分配比这更多的空间(它不会分配更少)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-09
      • 2016-02-10
      • 2012-04-17
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2017-11-30
      相关资源
      最近更新 更多