共计 924 个字符,预计需要花费 3 分钟才能阅读完成。
C++ 的 string 相对于 C 语言的 string 完善了很多,通过运算符重载可以很直观的进行字符串的拼接等操作。
GCC 5.0 以后的版本采用了__SSO__(短字符串优化)的策略替换了原本的__COW__优化,我写了几段代码来验证了一下新的实现的一些细节。
PS: 这里的所有的内容只是特定平台特定编译器的特定行为。
平台: Windows 64 位 MinGW 7.3.0
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
string a = “123456789abcde”; //15 个 char
string s(“this is the edge”); //16 个 char
string longstr(“Scaramouche, scaramouche will you do the Fandango”); // 长串 在 heap 分配
cout << &a << ” ” << (void*)a.c_str() << endl;
cout << &s << ” ” << (void*)s.c_str() << endl;
cout << &longstr << ” ” << (void*)longstr.c_str() << endl;
cout << sizeof(char*) << endl;
cout
<< sizeof(s) << endl;
return 0;
}
0x62fde0 0x62fdf0
0x62fdc0 0x7d17d0
0x62fda0 0x7d1b40
8
32
在这里我通过 c_str 打印串开始的地址。
从输出我们可以看出来 string 占 32 个字节, 其中 16 个字节实际上用于存储字符。
我们创建出来的三个对象地址相差 0x20(32)个字节, 后两个的指针地址于对象的地址相差很远,应该是在堆上动态分配的内存,而第一个字符串的存储地址 (0x62fdf0) 于对象的起始地址 (0x62fde0) 只差__0x10__, 而对象大小__0x20__, 所有这个串实际上就是存储在这个程序栈中.
上文的 SSO 实际上值得就是短的字符串 (strlen(s)<15, 即最多包含 15 个 char 和 ’0′) 直接存储在对象里,更长的串再存储在堆上开辟的空间里。
C++ 的 string 与 xstring 和 sds 在很多情况下很相像。