标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
来源:互联网 发布:成达工程公司 知乎 编辑:程序博客网 时间:2024/06/06 07:00
标准C++类std::string的内存共享,值得体会:
详见大牛:https://www.douban.com/group/topic/19621165/
顾名思义,内存共享,就是两个乃至更多的对象,共同使用一块内存;
1.关于string的内存共享问题:
通常,string类中必有一个私有成员,其是一个char*,用户记录从堆上分配内存的地址,其在构造时分配内存,在析构时释放内存。
因为是从堆上分配内存,所以string类在维护这块内存上是格外小心的,string类在返回这块内存地址时,只返回const char*,也就是只读的,
如果你要写,也只能通过string提供的方法进行数据的改写。
#include<iostream>#include<string>#include<cstdio>using namespace std; main(){ string str1 = "hello world"; string str2 = str1; string str3 = str2; printf ("内存共享:\n"); printf ("\tstr1 的地址: %x\n", (unsigned int)str1.c_str() ); printf ("\tstr2 的地址: %x\n", (unsigned int)str2.c_str() ); printf ("\tstr3 的地址: %x\n", (unsigned int)str3.c_str() ); return 0;}如上例子中,str1,str2,str3共享同一块内存,如图:
基本就是内存string类内存共享的最底层展现了,既然内存是一样的了,如果需要改写某个对象怎么办?由此引出写时拷贝Copy-On-Write
2.关于Copy-On-Write(原理)
顾名思义,写的时候在拷贝,(读的时候就不用了,哈哈)
还是以上边的例子为例:
#include<iostream>#include<string>#include<cstdio>using namespace std; main(){ string str1 = "hello world"; string str2 = str1; string str3 = str2; printf ("内存共享:\n"); printf ("\tstr1 的地址: %x\n", (unsigned int)str1.c_str() ); printf ("\tstr2 的地址: %x\n", (unsigned int)str2.c_str() ); printf ("\tstr3 的地址: %x\n", (unsigned int)str3.c_str() ); str3[1]='a'; str2[1]='w'; str1[1]='q'; printf ("通过写时拷贝之后:\n"); printf ("\tstr1 的地址: %x\n", (unsigned int)str1.c_str() ); printf ("\tstr2 的地址: %x\n", (unsigned int)str2.c_str() ); printf ("\tstr3 的地址: %x\n", (unsigned int)str3.c_str() ); return 0;}//输出结果:内存共享: str1 的地址: 83f9017 str2 的地址: 83f9017 str3 的地址: 83f9017通过写时拷贝之后: str1 的地址: 83f9017 str2 的地址: 83f9054 str3 的地址: 83f9034很明显可以看出来,一开始,str1,str2,str3共享同一块内存,地址都是一样的;
当开始修改是这些内存是,先不说如何实现,先表征是如何写时拷贝的,看图,咱还是看图:
图中依然说明了str3的内容修改是怎么回事,str2的内容修改,也是同样的道理,重新给str2在堆上开辟空间,原空间只是str1一个人用,修改最后一个str1的内容时,
当然就不用在和前两种一样啦,因为,这个时候,原空间只有str1一个人用,这个时候,对此空间操作,没有任何问题。都写都可以;
写时拷贝在此例中的体现,主要是str2,和str3内容的修改;但是有没有发现,我每次开辟空间的同时,会在新开辟的空间开头多分配一个空间,存放的是count;
原因就和写时拷贝的具体操作有关了:
3.写时拷贝(Copy-On-Write)的实现:
Copy-On-Write使用了“引用计数”,有一个变量count来计数,而且计数就放在没开辟一段空间的开头几个字节。
当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,
当有类析构时,这个计数会减一,直到最后一个类析构时,此时的count为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。
下面是我写的一个简单的例子:
#include<iostream>using namespace std;class String{public:String(const char* str)//初始时字符创有一个\0外加4个字节的引用计数空间:_str(new char[strlen(str)+5]){(*((int*)_str)) = 1;//申请的空间赋值为1_str += 4; //让_str还是指向字符创的第一个字符 //而不是引用计数的头上strcpy(_str,str);}String(const String& s):_str(s._str){(*(((int*)_str) - 1)) += 1;}String& operator=(const String& s){if(_str != s._str){if(*(((int*)_str) - 1) == 0){delete[] (_str-4);}_str = s._str;*(((int*)_str) - 1) += 1;}return *this;}~String(){if(*(((int*)_str) - 1) == 0){_str -= 4;delete[] _str;}}private:char *_str;};void Test(){String s1("11111111111111111111111111");String s2(s1);}int main(){Test();return 0;}在内存开头开辟引用计数空间;
到此,string类的内存共享和写时拷贝,就算是告一段落了,个人拙见,跪求赐教!
- 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术(1)
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和copy-on-write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术(转)
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术(转)
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的内存共享和Copy-On-Write技术
- 标准C++类std::string的 内存共享和Copy-On-Write技术
- std::string的内存共享和Copy-On-Write技术
- std string的内存共享和Copy-On-Write技术
- std::string的内存共享和Copy-On-Write技术
- C++实验5-求和
- 【转】分布式设计与开发(一)------宏观概述
- 【转】Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
- 试验发文
- Chromium网页光栅化过程分析
- 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
- NSOperation多线程的使用与理解
- 桶排序
- 织梦dedecms全自动采集的方法
- mcc、mbuild和mex命令详解
- 透过CAT,来看分布式实时监控系统的设计与实现
- 构造函数
- java中的一些基本语句
- Android电话服务