使用内存新主张CopyOnWrite(写时拷贝)

一、什么是写时拷贝技术
写时拷贝技术可以理解为“写的时候才去分配空间”,这实际上是一种拖延战术。
举个栗子:

二、写时拷贝技术原理:
  写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真的释放掉这块空间。当有的指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时引用计数的变化,旧的空间的引用计数减一,新分配的空间引用计数加一)。


利用写时拷贝技术实现简单string类

//声明文件

#pragma once
#include<string.h>
#include<stdlib.h>
#include<stdio.h>

#include<iostream>
using namespace std;


class CString{
public:
	char* lpszBuff;
public:
	CString(const char* buff = "");
	CString(CString& other);
	CString& operator=(CString& other);
	~CString();
	char& operator[](size_t index);
};


//实现文件

#include "StdAfx.h"
#include "CopyOnWrite.h"


CString::CString(const char* buff){
	cout << "CString构造函数" << endl;
	lpszBuff = new char[strlen(buff) + 1 + 4];//前4个字节用来存放引用计,最后一个字节用来存放结尾符
	int* pInt = (int*)lpszBuff; *pInt = 1;//引用计数的初始值设置成1  
	lpszBuff += 4; strcpy(lpszBuff, buff);
}
CString::CString(CString& other){
	cout << "CString拷贝构造函数" << endl;
	lpszBuff = other.lpszBuff;//此处的顺序很重要!!!
	int* pInt = (int*)(lpszBuff-4); (*pInt)++;
}
CString& CString::operator=(CString& other){
	cout << "CString赋值函数" << endl;
	if(this != &other){//防止自我复制
		int* pInt = (int*)(lpszBuff-4);
		if(--(*pInt) == 0){
			cout << "释放缓存:" << lpszBuff << endl;
			delete[] (lpszBuff-4); lpszBuff = NULL;
		}
		lpszBuff = other.lpszBuff;//此处的顺序很重要!!!
		pInt = (int*)(lpszBuff-4); (*pInt)++;
	}
	return *this;
}
CString::~CString(){
	cout << "CString析构函数" << endl;
	int* pInt = (int*)(lpszBuff-4);
	if(--(*pInt) == 0){
		cout << "释放缓存:" << lpszBuff << endl;
		delete[] (lpszBuff-4); lpszBuff = NULL;
	}
}
char& CString::operator[](size_t index){
	int* pInt = (int*)(lpszBuff-4);
	if(*pInt == 1)					return lpszBuff[index];
	(*pInt)--;
	char* lpszTmp = lpszBuff;
	lpszBuff = new char[strlen(lpszTmp)+1+4];
	lpszBuff += 4; strcpy(lpszBuff, lpszTmp);
	pInt = (int*)(lpszBuff-4); *pInt = 1;
	return lpszBuff[index];
}


//测试客户端

void main()
{
	CString str1 = "I love China !";
	CString str2 = str1;
	CString str3 = "How are you ?";

	str3 = str2;
	str3[1] = 'i';
}

猜你喜欢

转载自blog.csdn.net/knightonhourse/article/details/80003234