zoukankan      html  css  js  c++  java
  • copy on read & copy on write


    1
    #include <iostream> 2 #include <string> 3 using namespace std; 4 5 int main() { 6 string strA = "Copy on write"; 7 string strB = strA; 8 string strC = strA; 9 printf("strA: %p\r\n", strA.c_str()); 10 printf("strB: %p\r\n", strB.c_str()); 11 printf("strC: %p\r\n", strC.c_str()); 12 13 strA = "sdf"; 14 strB = "23ddf"; 15 strC = "adfkdanfkdnvkdfnvkfdv"; 16 printf("After writing:\r\n"); 17 printf("strA: %p\r\n", strA.c_str()); 18 printf("strB: %p\r\n", strB.c_str()); 19 printf("strC: %p\r\n", strC.c_str()); 20 21 return 0; 22 }

    运行结果:

    strA: 0x103c007d8
    strB: 0x103c007d8
    strC: 0x103c007d8
    After writing:
    strA: 0x103c00808
    strB: 0x103c00828
    strC: 0x103c00848
    [Finished in 0.2s]
    

    分析:

    9,10,11行printf输出的strA,strB,strC的C格式字符串的首地址全部相同,可见他们共享一份内存数据。

    看过《More Effective C++》的话,你知道这里运用了引用计数。到第9行为止"Copy on write"仅一份,引用计数为3.

    13行执行后"Copy on write"的引用计数变为2,执行15行时引用计数为1,那两次输出的strC的地址应该一致才对。但是strC地址确实变了,也就是说确实发生了写时拷贝。why?

    仔细看代码,发现原来strC之前的长度不够,因此strC还是会写时拷贝。

    现在把15行改成 strC = "adfkda"; 两次输出的strC的地址就会一致了。

    再看一个读时拷贝的例子:

    #include <iostream>
    #include <string>
    using namespace std;
     
    int main() {   
        string str1 = "hello world!";   
        string str2 = str1;   
        char* p1 = const_cast<char*>(str1.c_str());   
        p1[0] = 'T';
        printf("str1: %s \r\nstr2: %s\n", str1.c_str(), str2.c_str());
    
        string str3 = "hello world!";   
        string str4 = str3;   
        char* p2 = &(str3[0]);   
        p2[0] = 'g';   
        printf("str3: %s \r\nstr4: %s\n", str3.c_str(), str4.c_str());   
        return 0;   
    }

    运行结果:

    str1: Tello world! 
    str2: Tello world!
    str3: gello world! 
    str4: hello world!
    [Finished in 0.2s]
    

    使用c_str()方法取得str1的buf地址后,强转成了char*类型,并不会进行复制操作,只因c_str()只是一个读操作而已。当通过p1对buf进行修改后,str1和str2都被修改了。

    p2使用了[]操作符,String对[]进行了重载,当你通过[]获得String的buf地址的时候,编译器并不知道是读是写(尽管这里只是读取),保险起见,String内部会有一个变量进行控制,一旦遇到这种情况,则取消写时拷贝技术,因此str3改变了,但是str4指向的是另一块内存,并无影响。 

    在这里,const_cast<>()强制转换就是罪魁祸首。

    参见:《More Effective C++》引用计数这一章节

  • 相关阅读:
    转:关于国外硕博士论文搜索和下载的讨论
    转:如何查找别人论文(计算机类文献)中实验的代码?
    jQuery基础知识二
    jQuery基础知识笔记一
    jQuery基础知识一
    JS知识回顾
    JS的DOM(获取元素、元素属性、value属性、显示时间、计时器、节点增删改查等)
    JS基础知识三(正则表达式、arguments变量、JS事件、onsubmit事件、各种对象)
    JS基础知识小结二
    JS基础知识二(函数、全局/局部变量、对象、方法)
  • 原文地址:https://www.cnblogs.com/pure/p/2915265.html
Copyright © 2011-2022 走看看