当前位置: 代码迷 >> 综合 >> 写时复制Copy-On-Write
  详细解决方案

写时复制Copy-On-Write

热度:26   发布时间:2023-09-30 09:14:48.0
Copy-on-Write简称COW,不是奶牛,好处就是能保证数据的完整性,掉电的话容易恢复。
在执行复制和赋值的时候,不会真正的Copy,只有真正对内容进行修改时,才会进行复制,复制完之后再去修改-->懒复制
?Copy-On-Write一定使用了“引用计数”,必然有一个变量类似于RefCnt
?当第一个string对象str1构造时,string的构造函数会根据传入的参数从堆上分配内存
?当有其它string对象复制str1时,这个RefCnt会自动加1
?当有对象析构时,这个计数会减1;直到最后一个对象析构时,RefCnt为0,此时,程序才会真正的释放这块从堆上分配的内存



?在共享同一块内存的类发生 内容改变时,才会发生Copy-On-Write
?
?比如string类的 []、=、+=、+、操作符赋值,还有一些string类中诸如insert、replace、append等成员函数
?
#include <stdio.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;//std::string并不是线程安全的int main(void)
{string s1 = "hello,world";string s2 = s1;string s3 = s2;const char * p1 = s1.c_str();const char * p2 = s2.c_str();const char * p3 = s3.c_str();cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);printf("p3 = %p\n", p3);s3[0] = 'X';cout << "发生修改之后:" << endl;p1 = s1.c_str();p2 = s2.c_str();p3 = s3.c_str();cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);printf("p3 = %p\n", p3);return 0;
}

执行后的结果为:
s1 = hello,world
s2 = hello,world
s3 = hello,world
p1 = 0x204f028
p2 = 0x204f028
p3 = 0x204f028
发生修改之后:
s1 = hello,world
s2 = hello,world
s3 = Xello,world
p1 = 0x204f028
p2 = 0x204f028
p3 = 0x204f058

显而易见,当修改其内容时,发生Copy-On-Write

#include <stdio.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;//std::string并不是线程安全的int main(void)
{string s1 = "hello,world";string s2 = s1;string s3 = s2;const char * p1 = s1.c_str();const char * p2 = s2.c_str();const char * p3 = s3.c_str();cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);printf("p3 = %p\n", p3);s3[0] = 'X';cout << "发生修改之后:" << endl;p1 = s1.c_str();p2 = s2.c_str();p3 = s3.c_str();cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);printf("p3 = %p\n", p3);cout << endl;cout << "读取s2[0]之后" << endl;cout << s2[0] << endl;p1 = s1.c_str();p2 = s2.c_str();p3 = s3.c_str();cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;printf("p1 = %p\n", p1);printf("p2 = %p\n", p2);printf("p3 = %p\n", p3);return 0;
}

执行结果为:
s1 = hello,world
s2 = hello,world
s3 = hello,world
p1 = 0x211e028
p2 = 0x211e028
p3 = 0x211e028
发生修改之后:
s1 = hello,world
s2 = hello,world
s3 = Xello,world
p1 = 0x211e028
p2 = 0x211e028
p3 = 0x211e058读取s2[0]之后
h
s1 = hello,world
s2 = hello,world
s3 = Xello,world
p1 = 0x211e028
p2 = 0x211e088
p3 = 0x211e058



  相关解决方案