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++的stringxstringsds在很多情况下很相像。


phiysng
1 声望1 粉丝

K.I.S.S