当前位置: 首页 > 工具软件 > COW > 使用案例 >

C++ string的COW和SSO策略

墨财
2023-12-01


COW和SSO是什么?

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。


[1]. COW的弊端

COW使用引用计数的方式,在复制时只是简单地将引用计数+1,两者指向的是同一块空间,而只有当写操作(具有修改语意义的操作)时才会申请空间,此时引用计数会-1,如果引用计数为0,则释放内存。

string origin = "COW";
string copy = origin;

cout << boolalpha  << (origin.c_str() == copy.c_str())<< endl; //同一块空间,输出true

基于COW的实现方式,它在多线程环境下存在线程安全的问题,如多个线程同时进行写操作导致引用计数的不同步,而要避免多线程下的数据竞争,需要:

  1. 引用计数的原子性操作(加锁)
  2. 分配内存时引用计数不可操作,分配复制完后引用计数-1

[2]. SSO的优化

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策略可以查看对应编译器提供的源码。

 类似资料: