COW(Copy-On-Write):写时复制,即复制的时候不立即申请内存(浅拷贝),而在写操作的时候才开始申请内存进行复制。
SSO(Small String Optimization):短字符串优化,即复制时立即申请内存(深拷贝),但当字符串较短时存在栈中。
注意:C++11标准string不允许COW[参考21.4 Class template basic_string],目前大多数的编译器都抛弃了COW,转向SSO策略。
旧版本编译器如VC6或GCC 4采用COW,VC2010/GCC 5等编译器是SSO。
COW使用引用计数的方式,在复制时只是简单地将引用计数+1,两者指向的是同一块空间,而只有当写操作(具有修改语意义的操作)时才会申请空间,此时引用计数会-1,如果引用计数为0,则释放内存。
string origin = "COW";
string copy = origin;
cout << boolalpha << (origin.c_str() == copy.c_str())<< endl; //同一块空间,输出true
基于COW的实现方式,它在多线程环境下存在线程安全的问题,如多个线程同时进行写操作导致引用计数的不同步,而要避免多线程下的数据竞争,需要:
SSO的结构带有缓冲Buffer,当字符串较小(不同编译器/操作系统不一样)时直接存储在buffer中(栈),当字符串较长时存储在堆中。
string origin = "SSO";
string copy = origin;
cout << boolalpha << (origin.c_str() == copy.c_str())<< endl; //SSO直接分配空间,输出false
现代化的编译器大多数都是实现的SSO策略,我们在编码过程中不用太关注string的实现细节,但对于COW和SSO的基本概念要有基础的了解,更进一步的了解COW和SSO策略可以查看对应编译器提供的源码。