陈皓专栏 【空谷幽兰,心如皓月】

芝兰生于深谷,不以无人而不芳;君子修道立德,不为困穷而改节。

用户操作
[即时聊天] [发私信] [加为好友]
陈皓ID:haoel
485128次访问,排名97好友51人,关注者74
芝兰生于空谷,不以无人而不芳;君子修道立德,不为困穷而改节。
haoel的文章
原创 71 篇
翻译 0 篇
转载 0 篇
评论 1052 篇
陈皓的公告
Email & MSN
haoel@hotmail.com
最近评论
liuxi:LS 两个command都是命令的意思 例如 cc -o test.o -c -g test.c这样的命令.
targets : prerequisites ; command
command
这个的意思是命令你可以选择写在先决条件(prerequisites)的后面用分号隔开;也可以另起一行用tab开始些命令。
figoshen:楼上的,楼主的程序我跑了没有问题,你说的的多加(int*)是问题我觉得加不加都一样了
silvervi:大哥,文章有错误

在VS 2005里面加了断点专门跑了一下,对照局部变量里面虚函数表的实际地址,错误跟我之前想的一样,少了一次解引用

正确的应该如下

cout << "虚函数表地址:" << (int *)*(int *)(&b) << endl;

cout &……
miansha:走过留名

谢谢LZ,学习并谨记
new_my_program:我还是个学生,但就我们学生的角度来看,像清华大学出版社你们这些人是没资格出书的。一个老师如果教育学生犯罪那就是个垃圾老师,你们出书的本来更是影响几代人,比一般的老师的影响力更大的多,你们的垃圾程度是可想而知的。以前看了《清华梦的破灭》这个文章后,我对心目中的清华园产生了严重的鄙视,现在再看了陈皓大哥的帖子,我更是鄙视你们。进清华的学生是何等的厉害,何等的意气风发。但是出清华的学生呢,好的就留……
文章分类
收藏
    相册
    我的BLOG
    耗子小筑(非技术)(RSS)
    陈皓专栏(技 术)(RSS)
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 标准C++类string的Copy-On-Write技术(一)收藏

    新一篇: 标准C++类string的Copy-On-Write技术(二) | 旧一篇: 跟我一起写 Makefile(九)

    标准C++类std::string的

    内存共享和Copy-On-Write技术

     

    陈皓

    1、             概念

     

    Scott Meyers在《More Effective C++》中举了个例子,不知你是否还记得?在你还在上学的时候,你的父母要你不要看电视,而去复习功课,于是你把自己关在房间里,做出一副正在复习功课的样子,其实你在干着别的诸如给班上的某位女生写情书之类的事,而一旦你的父母出来在你房间要检查你是否在复习时,你才真正捡起课本看书。这就是“拖延战术”,直到你非要做的时候才去做。

     

    当然,这种事情在现实生活中时往往会出事,但其在编程世界中摇身一变,就成为了最有用的技术,正如C++中的可以随处声明变量的特点一样,Scott Meyers推荐我们,在真正需要一个存储空间时才去声明变量(分配内存),这样会得到程序在运行时最小的内存花销。执行到那才会去做分配内存这种比较耗时的工作,这会给我们的程序在运行时有比较好的性能。必竟,20%的程序运行了80%的时间。

     

    当然,拖延战术还并不只是这样一种类型,这种技术被我们广泛地应用着,特别是在操作系统当中,当一个程序运行结束时,操作系统并不会急着把其清除出内存,原因是有可能程序还会马上再运行一次(从磁盘把程序装入到内存是个很慢的过程),而只有当内存不够用了,才会把这些还驻留内存的程序清出。

     

    写时才拷贝(Copy-On-Write)技术,就是编程界“懒惰行为”——拖延战术的产物。举个例子,比如我们有个程序要写文件,不断地根据网络传来的数据写,如果每一次fwrite或是fprintf都要进行一个磁盘的I/O操作的话,都简直就是性能上巨大的损失,因此通常的做法是,每次写文件操作都写在特定大小的一块内存中(磁盘缓存),只有当我们关闭文件时,才写到磁盘上(这就是为什么如果文件不关闭,所写的东西会丢失的原因)。更有甚者是文件关闭时都不写磁盘,而一直等到关机或是内存不够时才写磁盘,Unix就是这样一个系统,如果非正常退出,那么数据就会丢失,文件就会损坏。

     

    呵呵,为了性能我们需要冒这样大的风险,还好我们的程序是不会忙得忘了还有一块数据需要写到磁盘上的,所以这种做法,还是很有必要的。

     

     

    2、             标准C++std::stringCopy-On-Write

     

    在我们经常使用的STL标准模板库中的string类,也是一个具有写时才拷贝技术的类。C++曾在性能问题上被广泛地质疑和指责过,为了提高性能,STL中的许多类都采用了Copy-On-Write技术。这种偷懒的行为的确使使用STL的程序有着比较高要性能。

     

    这里,我想从C++类或是设计模式的角度为各位揭开Copy-On-Write技术在string中实现的面纱,以供各位在用C++进行类库设计时做一点参考。

     

    在讲述这项技术之前,我想简单地说明一下string类内存分配的概念。通过常,string类中必有一个私有成员,其是一个char*,用户记录从堆上分配内存的地址,其在构造时分配内存,在析构时释放内存。因为是从堆上分配内存,所以string类在维护这块内存上是格外小心的,string类在返回这块内存地址时,只返回const char*,也就是只读的,如果你要写,你只能通过string提供的方法进行数据的改写。

     

    2.1、         特性

     

    由表及里,由感性到理性,我们先来看一看string类的Copy-On-Write的表面特征。让我们写下下面的一段程序:

     


    #include

    #include

    using namespace std;

     

    main()

    {

           string str1 = "hello world";

           string str2 = str1;

          

           printf ("Sharing the memory:\n");

           printf ("\tstr1's address: %x\n", str1.c_str() );

           printf ("\tstr2's address: %x\n", str2.c_str() );

          

        str1[1]='q';

           str2[1]='w';

     

           printf ("After Copy-On-Write:\n");

           printf ("\tstr1's address: %x\n", str1.c_str() );

           printf ("\tstr2's address: %x\n", str2.c_str() );

     

           return 0;

    }

     

    这个程序的意图就是让第二个string通过第一个string构造,然后打印出其存放数据的内存地址,然后分别修改str1str2的内容,再查一下其存放内存的地址。程序的输出是这样的(我在VC6.0g++ 2.95都得到了同样的结果):

     


    > g++ -o stringTest stringTest.cpp

    > ./stringTest

    Sharing the memory:

            str1's address: 343be9

            str2's address: 343be9

    After Copy-On-Write:

            str1's address: 3407a9

            str2's address: 343be9

     

    从结果中我们可以看到,在开始的两个语句后,str1str2存放数据的地址是一样的,而在修改内容后,str1的地址发生了变化,而str2的地址还是原来的。从这个例子,我们可以看到string类的Copy-On-Write技术。

     

     下一页->

    (版权所有,转载时请注明作者和出处)

    发表于 @ 2004年06月23日 16:06:00|评论(loading...)|编辑

    新一篇: 标准C++类string的Copy-On-Write技术(二) | 旧一篇: 跟我一起写 Makefile(九)

    评论

    #wanggang999 发表于2004-12-03 12:04:00  IP: 218.24.185.*

    我在自己的Blog上转载了你的一篇文章,

    你的Blog的字体设置太小了,看着累,不过还好斯感谢你的文章,我觉得写得挺好的,


    ----一个还在学习C++的菜鸟----
    #yingshanren 发表于2005-02-01 14:54:00  IP: 222.210.195.*
    写的太好了
    #lzhongsh 发表于2005-04-09 10:26:00  IP: 211.81.244.*
    我在VC.NET下试了,不支持写时拷贝啊
    #笑笑生 发表于2006-03-16 15:29:00  IP: 222.91.73.*
    VC2003结果:好象只用了一般实现
    Sharing the memory:
    str1's address: 12feb4
    str2's address: 12fe90
    After Copy-On-Write:
    str1's address: 12feb4
    str2's address: 12fe90
    Press any key to continue
    #aa 发表于2006-05-20 23:22:00  IP: 211.138.164.*
    以前还真没注意呢
    Sun OS
    Sharing the memory:
    str1's address: 412e8
    str2's address: 412e8
    After Copy-On-Write:
    str1's address: 41328
    str2's address: 412e8
    WIN 下VC2003确实没使用
    #aa 发表于2006-05-20 23:22:00  IP: 211.138.164.*
    以前还真没注意呢
    Sun OS CC
    Sharing the memory:
    str1's address: 412e8
    str2's address: 412e8
    After Copy-On-Write:
    str1's address: 41328
    str2's address: 412e8
    WIN 下VC2003确实没使用
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 陈皓