我只是好奇,字符串是如何存储在内存中的?例如,当我这样做时:
string testString = "asd";
它分配4个字节,对吗? a + s + d + \0
。
但是后来,当我想为这个字符串分配一些新文本时,它可以工作,但我不明白怎么做。例如,我这样做:
testString = "123456789"
现在它应该是10个字节长。但是如果没有这种字符串的空间呢?假设字符串开头的第五个+第六个字节被其他一些字符占用。 CPU如何处理它?它在内存中找到了全新的位置,该字符串适合吗?
答案 0 :(得分:12)
这是依赖于实现的,但一般的想法是字符串类将包含指向存储字符串的实际内容的内存区域的指针。两个常见的实现是存储3个指针(分配的区域和数据的开始,数据的结尾,分配的区域的结束)或指针(分配的区域和数据的开始)和两个整数(字符串中的字符数和分配的数量)字节)。
当新数据附加到字符串时,如果它适合分配的区域,则只会写入,并且数据指针的大小/结尾将相应地更新。如果数据不适合该区域,则将创建新缓冲区并复制数据。
另请注意,许多实现都对小字符串进行了优化,其中字符串类包含一个小缓冲区。如果字符串的内容适合缓冲区,则不会动态分配内存,只使用本地缓冲区。
答案 1 :(得分:4)
string
不是像char *
这样的简单数据类型。它是类,它具有不一定可见的实现细节。
除其他事项外,string
还包括一个计数器,用于记录它的真实程度。
char[] test = "asd"; // allocates exactly 4 bytes
string testString = "asd"; // who knows?
testString = "longer"; // allocates more if necessary
建议:编写一个简单的程序,并使用调试器逐步完成。检查string
,看看私有成员在值发生变化时如何变化。
答案 2 :(得分:2)
string
是一个对象,而不仅仅是一些内存位置。它根据需要动态分配内存。
=
运算符已超载;当您说testString = "123456789";
正在调用某个方法并处理您传入的const char *
时。
答案 3 :(得分:2)
它以大小存储。如果存储新字符串,它将可选择释放现有内存并分配新内存以应对大小的变化。
第一次为其分配4个字节的字符串时,它不一定会分配4个字节。它可能会分配更多的空间(它不会分配更少)。