LoveBeyond

Copy On Write(写时复制)

(本文最初发表于程序人生 >> Copy On Write(写时复制) 作者:代码疯子

Copy On Write(写时复制)是在编程中比较常见的一个技术,面试中也会偶尔出现(好像Java中就经常有字符串写时复制的笔试题),今天在看《More Effective C++》的引用计数时就讲到了Copy On Write——写时复制。下面简单介绍下Copy On Write(写时复制),我们假设STL中的string支持写时复制(只是假设,具体未经考证,这里以Mircosoft Visual Studio 6.0为例,如果有兴趣,可以自己翻阅源码)

Copy On Write(写时复制)的原理是什么?
有一定经验的程序员应该都知道Copy On Write(写时复制)使用了“引用计数”,会有一个变量用于保存引用的数量。当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的引用计数为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。
引用计数就是string类中写时才拷贝的原理!

什么情况下触发Copy On Write(写时复制)
很显然,当然是在共享同一块内存的类发生内容改变时,才会发生Copy On Write(写时复制)。比如string类的[]、=、+=、+等,还有一些string类中诸如insert、replace、append等成员函数等,包括类的析构时。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 作者:代码疯子
// 博客:http://www.programlife.net/
// 引用计数 & 写时复制
#include <iostream>
#include <string>
using namespace std;
 
int main(int argc, char **argv)
{
	string sa = "Copy on write";
	string sb = sa;
	string sc = sb;
	printf("sa char buffer address: 0x%08X\n", sa.c_str());
	printf("sb char buffer address: 0x%08X\n", sb.c_str());
	printf("sc char buffer address: 0x%08X\n", sc.c_str());
 
	sc = "Now writing...";
	printf("After writing sc:\n");
	printf("sa char buffer address: 0x%08X\n", sa.c_str());
	printf("sb char buffer address: 0x%08X\n", sb.c_str());
	printf("sc char buffer address: 0x%08X\n", sc.c_str());
 
	return 0;
}

输出结果如下(VC 6.0):
Copy On Write(写时复制)
可以看到,VC6里面的string是支持写时复制的,但是我的Visual Studio 2008就不支持这个特性(Debug和Release都是):
Visual Studio 2008不支持Copy On Write(写时复制)

拓展阅读:(摘自《Windows Via C/C++》5th Edition,不想看英文可以看中文的PDF,中文版第442页)
Static Data Is Not Shared by Multiple Instances of an Executable or a DLL

您可能对下面的文章也感兴趣:
  1. ISCC2011基础关-小明的程序 (10.4)
  2. 一些Win32汇编知识 (7)
  3. 一个C语言结构体问题 (6.3)
  4. 第二届顶嵌杯决赛解题报告与总结 (6.2)
  5. 空白基类最优化 The Empty Base Class Optimization (EBCO) (5.6)
原创文章,转载请注明:
本文出自程序人生 >> Copy On Write(写时复制)
作者:代码疯子

posted on 2011-09-30 08:58 LoveBeyond 阅读(3319) 评论(5)  编辑 收藏 引用 所属分类: 杂乱无章

<2012年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

留言簿(1)

文章分类

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

友情链接:C++博客 LoveBeyond 代码疯子 程序人生 C++技术博客