String类的实现(4)写时拷贝浅析
由于释放内存空间,开辟内存空间时花费时间,因此,在我们在不需要写,只是读的时候就可以不用新开辟内存空间,就用浅拷贝的方式创建对象,当我们需要写的时候才去新开辟内存空间。这种方法就是写时拷贝。这也是一种解决由于浅拷贝使多个对象共用一块内存地址,调用析构函数时导致一块内存被多次释放,导致程序奔溃的问题。这种方法同样需要用到引用计数:使用int *保存引用计数;采用所申请的4个字节空间。
#include<iostream>
#include<stdlib.h>
using namespace std;
class String
{
public:
String(const char *pStr = "")
{
if (pStr == NULL)
{
_pStr = + ];
*((;
_pStr = ();
*_pStr = '\0';
}
else
{
_pStr = + ];
my_strcopy(_pStr, pStr);
*(() = ;
}
}
String(const String& s)
:_pStr(s._pStr)
{
++GetCount();
}
~String()
{
Release();
}
String& operator=(const String& s)
{
if (this != &s)
{
Release();
_pStr = s._pStr;
--(GetCount());
}
return *this;
}
char& operator[](size_t index)//写时拷贝
{
) //当引用次数大于1时新开辟内存空间
{
+ ];
my_strcopy(pTem + , _pStr);
--GetCount(); //原来得空间引用计数器减1
_pStr = pTem + ;
GetCount() = ;
}
return _pStr[index];
}
const char& operator[](size_t index)const
{
return _pStr[index];
}
friend ostream& operator<<(ostream& output, const String& s)
{
output << s._pStr;
return output;
}
private:
int& GetCount()
{
);
}
void Release()
{
== --GetCount()))
{
_pStr = ();
delete _pStr;
}
}
char *_pStr;
};
int main()
{
String s1;
String s2 = ";
String s3(s2);
s2[] = ';
String s4;
s3 = s4;
}
写时拷贝能减少不必要的内存操作,提高程序性能,但同时也是一把双刃剑,如果没按 stl 约定使用 String ,可能会导致极其严重的 bug ,而且通常是很隐蔽的,因为一般不会把注意力放到一个赋值语句。修改 String 数据时,先判断计数器是否为 0( 0 代表没有其他对象共享内存空间),为 0 则可以直接使用内存空间(如上例中的 s2 ),否则触发写时拷贝,计数 -1 ,拷贝一份数据出来修改,并且新的内存计数器置 0 ; string 对象析构时,如果计数器为 0 则释放内存空间,否则计数也要 -1 。
写时拷贝存在的线程安全问题
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。String类写时拷贝可能存在的问题详见:http://blog.csdn.net/haoel/article/details/24077
String类的实现(4)写时拷贝浅析的更多相关文章
- 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
标准C++类std::string的内存共享,值得体会: 详见大牛:https://www.douban.com/group/topic/19621165/ 顾名思义,内存共享,就是两个乃至更多的对象 ...
- String 类的实现(2)引用计数与写时拷贝
1.引用计数 我们知道在C++中动态开辟空间时是用字符new和delete的.其中使用new test[N]方式开辟空间时实际上是开辟了(N*sizeof(test)+4)字节的空间.如图示其中保存N ...
- String写时拷贝实现
头文件部分 1 /* 版权信息:狼 文件名称:String.h 文件标识: 摘 要:对于上版本简易的String进行优化跟进. 改进 1.(将小块内存问题与大块分别对待)小内存块每个对象都有,当内存需 ...
- 计算机程序的思维逻辑 (73) - 并发容器 - 写时拷贝的List和Set
本节以及接下来的几节,我们探讨Java并发包中的容器类.本节先介绍两个简单的类CopyOnWriteArrayList和CopyOnWriteArraySet,讨论它们的用法和实现原理.它们的用法比较 ...
- 并发容器之写时拷贝的 List 和 Set
对于一个对象来说,我们为了保证它的并发性,通常会选择使用声明式加锁方式交由我们的 Java 虚拟机来完成自动的加锁和释放锁的操作,例如我们的 synchronized.也会选择使用显式锁机制来主动的控 ...
- Java编程的逻辑 (73) - 并发容器 - 写时拷贝的List和Set
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- 写时拷贝(Copy On Write)方案详解
本文旨在通过对 写时拷贝 的四个方案(Copy On Write)分析,让大家明白写时拷贝的实现及原理. 关于浅拷贝与深拷贝,我在之前的博客中已经阐述过了 浅拷贝容易出现指针悬挂的问题,深拷贝效率低 ...
- rust漫游 - 写时拷贝 Cow<'_, B>
rust漫游 - 写时拷贝 Cow<'_, B> Cow 是一个写时复制功能的智能指针,在数据需要修改或者所有权发生变化时使用,多用于读多写少的场景. pub enum Cow<'a ...
- Linux写时拷贝技术(copy-on-write)
COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内 ...
随机推荐
- C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(上)
译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章 ASP.NET Core(上)),不对的地方欢迎指出与交流. 章节出自<Professiona ...
- Redis 学习之持久化机制、发布订阅、虚拟内存
一.持久化机制 Redis是一个支持持久化的内存数据库,redis会经常将内存中的数据同步到硬盘上来保证数据持久化,从而避免服务器宕机数据丢失问题,或者减少服务器内存消耗提高性能. 持久化方式: 1. ...
- Swift3.0 中 Strings/Characters 闲聊
前言 本篇文章主要浅析字符串\字符在 Swift 和 Objective-C 之间的区别及其简单用法.如有不妥的地方还望大家及时帮忙纠正. 字符串判空 在 swift 语言中空字符串初始化方式常用的有 ...
- MVC,MVP,MVVM
MVC模式: MVC即Model-VIew-Controller.他是1970年代被引入到软件设计大众的.MVC模式致力于关注点的切分,这意味着model和controller的逻辑是不与用户界面(V ...
- Asp.net mvc 知多少(八)
本系列主要翻译自<ASP.NET MVC Interview Questions and Answers >- By Shailendra Chauhan,想看英文原版的可访问[http: ...
- java中使用正则表达式匹配字符串
在Java中使用正则表达式去匹配相应的字符串: String importFileRole = "(import)\\s*[a-zA-Z0-9_<>.]+\\;";// ...
- 支持缩放的fresco图片控件 —— fresco sample: ZoomableDraweeView
最近在实现一个类似淘宝中的评论列表的功能,其中要在列表中显示评论图,点击图片后显示大图进行查看,各家app几乎都会有这样的功能. 可以看到,一个体验较好的查看大图的基本功能有, 第一,左右滑动时切换图 ...
- MVC和三层架构
从最开始写程序到现在,一路上听到架构这个词已经无数次了,在工作和圈子里也不停听到大家在讨论它,但是很多时候发现不少人对这个概念的理解都是很模糊的,无意间在知道上看到一个朋友的回答,感觉很不错,特转帖到 ...
- storm 1.0版本滑动窗口的实现及原理
滑动窗口在监控和统计应用的场景比较广泛,比如每隔一段时间(10s)统计最近30s的请求量或者异常次数,根据请求或者异常次数采取相应措施.在storm1.0版本之前,没有提供关于滑动窗口的实现,需要开发 ...
- 安装 MySQL 后,需要调整的 10 个性能配置项
注意:这篇博文的更新版本在这儿,MySQL 5.7 适用! 原文:Ten MySQL performance tuning settings after installation 在本文中,我们将探讨 ...