原作地址:
http://hi.baidu.com/jakisou/blog/item/255e9cd66f16a72a06088b20.html
1、概念
Scott Meyers在《More Effective C++》 中举了个例子,不知你是否还记得?在你还在上学的时候,你的父母要你不要看电视,而去复习功课,于是你把自己关在房间里,做出一副正在复习功课的样子,其 实你在干着别的诸如给班上的某位女生写情书之类的事,而一旦你的父母出来在你房间要检查你是否在复习时,你才真正捡起课本看书。这就是“拖延战术”,直到 你非要做的时候才去做。
当然,这种事情在现实生活中时往往会出事,但其在编程世界中摇身一变,就成为了最有用的技术,正如C++中的可以随处声明变量的特点一样,Scott Meyers推荐我们,在真正需要一个存储空间时才去声明变量(分配内存),这样会得到程序在运行时最小的内存花销。执行到那才会去做分配内存这种比较耗时的工作,这会给我们的程序在运行时有比较好的性能。必竟,20%的程序运行了80%的时间。
当 然,拖延战术还并不只是这样一种类型,这种技术被我们广泛地应用着,特别是在操作系统当中,当一个程序运行结束时,操作系统并不会急着把其清除出内存,原 因是有可能程序还会马上再运行一次(从磁盘把程序装入到内存是个很慢的过程),而只有当内存不够用了,才会把这些还驻留内存的程序清出。
写时才拷贝(Copy-On-Write)技术,就是编程界“懒惰行为”——拖延战术的产物。举个例子,比如我们有个程序要写文件,不断地根据网络传来的数据写,如果每一次fwrite或是fprintf都要进行一个磁盘的I/O操 作的话,都简直就是性能上巨大的损失,因此通常的做法是,每次写文件操作都写在特定大小的一块内存中(磁盘缓存),只有当我们关闭文件时,才写到磁盘上 (这就是为什么如果文件不关闭,所写的东西会丢失的原因)。更有甚者是文件关闭时都不写磁盘,而一直等到关机或是内存不够时才写磁盘,Unix就是这样一个系统,如果非正常退出,那么数据就会丢失,文件就会损坏。
呵呵,为了性能我们需要冒这样大的风险,还好我们的程序是不会忙得忘了还有一块数据需要写到磁盘上的,所以这种做法,还是很有必要的。
2、 标准C++类std::string的Copy-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构造,然后打印出其存放数据的内存地址,然后分别修改str1和str2的内容,再查一下其存放内存的地址。程序的输出是这样的(我在VC6.0和g++ 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
|
从结果中我们可以看到,在开始的两个语句后,str1和str2存放数据的地址是一样的,而在修改内容后,str1的地址发生了变化,而str2的地址还是原来的。从这个例子,我们可以看到string类的Copy-On-Write技术。
写时拷贝可以提高STL库的效率,但是在我们使用它的时候很容易遇到一些陷阱。
看这个例子,这是看到别人分享的问题,本意肯定不愿意str2的值被修改,但是由于STL认为
char*p1=const_cast<char*>(str1.c_str());
str1.c_str()这步操作返回的是const char*对象,不会导致写操作,所以没有对str1对象进行拷贝处理,而const_cast<char*>在强制转换后赋值给p1后,后续的写操作导致了悲剧发生。
原因分析完了,如何解决,很简单,保证写操作之前,STL已经对该对象拷贝出了内存,方法就见仁见智了。
分享到:
相关推荐
### MSTL_JGF_04-018-2006 信息安全技术日志分析产品检验规范 #### 一、概述 MSTL_JGF_04-018-2006《信息安全技术日志分析产品检验规范》是一项重要的行业标准,旨在规定日志分析产品的安全功能要求和安全保证要求...
使用X-CUBE-STL库时,必须遵循安全手册和相应微控制器用户指南中的具体要求。此外,证书的有效期至2023年6月6日。证书的颁发基于2018年6月6日完成的审查报告(报告编号968/FSP 1627.00/18)的结果。 TUV Rheinland...
本标准由全国信息技术标准化技术委员会(SAC/TC28)提出并归口。 本标准起草单位:中国科学院信息工程研究所(信息安全国家重点实验室)、国家信息中心、浪潮软件集团有限公司、智慧神州(北京)科技有限公司、方正国际软件...
title: STL源码剖析-容器-slist- 笔记description: slist也就是single linked list(单向链表)。slist与l
X-CUBE-STL-H7 安全手册知识点 X-CUBE-STL-H7 安全手册是 STMicroelectronics 公司为 STM32H7 系列微控制器发布的一份软件扩展包,旨在帮助用户快速实现安全应用程序。以下是该手册中涉及到的知识点: 1. 安全机制...
方便侧睡的stl模型,文件不大。stl模型-机器小人-测试模型
本文将比较 STL 字符串、copy-on-write 算法和非 copy-on-write 算法在性能方面的差异,并且讨论 GNU libstdc++ 和 STLport 实现的字符串性能。同时,本文还将讨论 fstream 和 stringstream 的性能问题。 在讨论...
3. 算法:STL包含了一系列通用算法,如排序(sort)、查找(find)、拷贝(copy)等,这些算法可以应用于任何类型的容器,只要提供相应的迭代器。例如,`std::sort`可以对容器中的元素进行排序,`std::find`可以查找...
STL包含了一套高效的算法库,如find、sort、copy、unique等,可以操作容器中的元素。例如,`find`用于查找特定元素,`for_each`用于对容器中的每个元素应用函数,`sort`则用于对容器元素进行排序。 4. **函数对象...
作为stl入门来说, 首推C++ STL程序员开发指南和标准模板库自修教程和参考, 看完这两本书之后, 对于C++_STL_开发技术导引-cdrom中的代码阅读应该不成 问题, 如果还是有困难, 那你可能需要重修一下C++程序设计. 中级...
侯捷翻译的STL源码剖析电子完全版,不是网上流传的只有四章的电子版,学习STL必备利器。-Hou Jie translation STL source code analysis electronic full version, not the spread of the Internet is only four ...
### 关于embo2021-pmr-STL-for-Embedded-Applications-en.pdf的知识点解析 #### 一、引言 本文档主要介绍了C++17中的Polymorphic Memory Resources (pmr) 和标准模板库(STL)容器在嵌入式应用中的应用。文档由...
作为stl入门来说, 首推C++ STL程序员开发指南和标准模板库自修教程和参考, 看完这两本书之后, 对于C++_STL_开发技术导引-cdrom中的代码阅读应该不成 问题, 如果还是有困难, 那你可能需要重修一下C++程序设计. 中级...
"stl-view.rar" 是一个压缩包,其中包含了一个名为 "stl-view" 的小软件,这个软件专门用于查看STL文件。用户可以通过这个工具自由地旋转3D模型,以便从不同角度检查模型的细节。对于设计师、工程师和3D打印爱好者来...
numpy_stl-2.16.0-cp38-cp38-win32
STL源码剖析(简体-非清晰-完整版)pdf格式-part2
STL源码剖析(简体-非清晰-完整版)pdf格式-part1