1. 程式人生 > >寫時拷貝(Copy On Write)方案詳解

寫時拷貝(Copy On Write)方案詳解

class String
{
public:
           String(char * str = "" )    //不能strlen(NULL)
           {
                    _str = new char[strlen( str) + 5];
                    _str += 4;
                    strcpy(_str, str);
                    GetRefCount(_str) = 1;
           }
           String(const String &s)
           {
                    _str = s._str;
                    ++GetRefCount(_str);
           }
 
           //要考慮是s1=s2時,s1原先不為空的情況,要先釋放原記憶體
           //如果要釋放原記憶體時,要考慮它的_refCount減1後是否為0,
           //為零再釋放,否則其它物件指標無法再訪問這片空間
           String& operator=(String& s)
           {
                    if (this != &s )
                    {
                              if (GetRefCount(_str ) == 1)
                              {
                                       delete (_str-4);
                                       _str = s._str;
                                       ++GetRefCount(_str );
                              }
                              else
                              {
                                       --GetRefCount(_str );
                                       _str = s._str;
                                       ++GetRefCount(_str );
                              }
                    }
                    return *this ;
           }
           //如果修改了字串的內容,那所有指向這塊記憶體的物件指標的內容間接被改變
           //如果還有其它指標指向這塊記憶體,我們可以從堆上重新開闢一塊記憶體空間,
           //把原字串拷貝過來.
           //再去改變它的內容,就不會產生鏈式反應
            
          
           char& String ::operator[](const size_t index ) //深拷貝     
           {
                    
                              if (GetRefCount(_str) == 1)
                              {
                                       return _str[index ];
                              }
                              else
                              {
                                        //  1.減引用計數
                                       --GetRefCount(_str );
                                        //  2.拷貝     3.建立新的引用計數
                                       char* tmp = new char [strlen(_str) + 5];   
                                      *((int *)tmp) = 1;
                                       tmp += 4;
                                       strcpy(tmp, _str);
                                       _str = tmp;
                                       return _str[index ];
                              }
           }
 
           int& GetRefCount(char* ptr)    //獲取引用計數(隱式行內函數)
           {
                    return *((int *)(ptr -4));
           }
           ~String()
           {
                    if (--GetRefCount(_str) == 0)
                    {
                              cout << "~String" << endl;
                              delete[] (_str-4);             
                    }
           
           }
           friend ostream& operator<<( ostream& output, const String &s);
           friend istream& operator>>( istream& input, const String &s);
private:
           char* _str;
 
};
 
 
ostream& operator<<(ostream& output, const String &s)
{
           output << s._str;
           return output;
}
istream& operator>>(istream& input, const String &s)
{
           input >> s._str;
           return input;
}
 
void Test()  //用例測試
{
           String s1("abcdefg" );
           String s2(s1);
           String s3;
           s3 = s2;
           cout << s1 << endl;
           cout << s2 << endl;
           cout << s3 << endl;
           s2[3] = '0';
           cout << s1 << endl;
           cout << s2 << endl;
           cout << s3 << endl;
} 

相關推薦

拷貝Copy On Write方案

class String { public: String(char * str = "" ) //不能strlen(NULL) { _str = new char[strlen( str) + 5];

PHP中的複製Copy On Write

問題引入   首先來看看PHP中的賦值與引用問題 <?php $a = 10;//將常量值賦給變數,會為a分配記憶體空間 $b = $a;//變數賦值給變數,是不是copy了一份副本,b也分配了記憶體空間呢? $c = &$a;//引用是不

Linux拷貝技術(copy-on-write)

轉自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html COW技術初窺:       在Linux程式中,fork()會產生一個和父程序完全相同的子程序,但子程序在此後多會exec系統呼叫,出於效率考慮,linux中引入了“

Linux拷貝技術(copy-on-write)

但是 現在 進程地址空間 優化 如何 進程創建 http exe fork COW技術初窺: 在Linux程序中,fork()會產生一個和父進程完全相同的子進程,但子進程在此後多會exec系統調用,出於效率考慮,linux中引入了“寫時復制“技術,也就是只有進程

Linux拷貝技術(copy-on-write)及fork、vfork流程介紹

COW技術初窺:       在Linux程式中,fork()會產生一個和父程序完全相同的子程序,但子程序在此後多會exec系統呼叫,出於效率考慮,linux中引入了“寫時複製“技術,也就是隻有程序空間的各段的內容要發生變化時,才會將父程序的內容複製一份給子程序。       那麼子程序的物理空間沒有程式碼

拷貝技術(copy-on-write)

 傳統的fork()系統呼叫直接把所有的資源複製給新建立的程序。這種實現過於簡單並且效率低下,因為它拷貝的資料也許並不共享,更糟的情況是,如果新程序打算立即執行一個新的映像,那麼所有的拷貝都將前功盡棄。Linux的fork()使用寫時拷貝(copy-on-write)頁實現

從win32中的複製Copy on write )機制談起

我們知道,記憶體對映檔案的物理儲存器來自磁碟上已有的檔案,而不是來自也交換檔案。系統在載入exe和dll檔案的時候使用的是記憶體對映檔案來載入並執行exe和dll,這樣大大節省了頁交換檔案的空間以及應用程式的啟動時間。所以,實際上系統載入exe檔案的時候就是利用記憶體對映檔

拷貝COWcopy-on-write

display 語句 namespace div str pre style -a [0 寫時拷貝技術是通過"引用計數"實現的,在分配空間的時候多分配4個字節,用來記錄有多少個指針指向塊空間,當有新的指針指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數減一

string類的簡單實現拷貝Copy-on-write

前言:上一篇文章實現了string的深拷貝寫法;那我們能不能用淺拷貝寫string類呢?當然可以; 一、 (1) 當我們需要對拷貝之後的物件進行修改時,採用深拷貝的方式; 如果不需要修改,只是輸出字串的內容時,或者是當偶爾修改的的時候,我們再採用深拷貝的方

C++ string 類 部分成員函式實現實現COW copy-on-write

雖然標題中說實現了COW,但是事實上是很浪費的,並且命名也很不標準,程式碼也非常小學生,畢竟初學(給自己找藉口.jpg),以後應該還會把這篇找出來認真修改一下的。 Mystring.h: #pragma once #ifndef _MYSTRING_H_ #define

寫實拷貝技術 copy-on-write

COW技術初窺: 在Linux程式中,fork()會產生一個和父程序完全相同的子程序,但子程序在此後多會exec系統呼叫,出於效率考慮,linux中引入了“寫時複製“技術,也就是隻有程序空間的各段的內容要發生變化時,才會將父程序的內容複製一份給子程序。 那麼子程序的物理空間

DPMDeformable Part Model原理匯總

特征向量 成就 算法思想 filter people tell 梯度 錨點 精度 寫在前面: DPM(Deformable Part Model),正如其名稱所述,可變形的組件模型,是一種基於組件的檢測算法,其所見即其意。該模型由大神Felzenszwalb在2008年提

java利用myeclipse自帶三大框架搭建三大框架Hibernate+Struts2+Spring過程

sun 過程 9.png att alt 分享圖片 struts apach sch 搭建過程因人而異,我的搭建過程大致是這樣的:   1.創建一個javaweb項目;   2.導入Spring框架,上圖:     2.1:     2.2:     2.3:   3.

第九篇Iptables

練習 etc 條目 root 第九篇 包括 路由選擇 網絡掃描 轉發 常見的網絡攻擊形式 1.拒絕服務攻擊:DOS 2.分布式拒絕服務攻擊 DDOS 3.漏洞入侵 4.口令猜測 以上內容簡單了解,具體可自行百度,此處不必知曉。 Linux防火墻基礎 Linux防火墻體系主要

數據結構 - 紅黑樹Red Black Tree插入與實現Java

啟示 dpa con 技術分享 節點數 src 通知 一點 this   最終還是決定把紅黑樹的篇章一分為二,插入操作一篇,刪除操作一篇,因為合在一起寫篇幅實在太長了,寫起來都覺得累,何況是閱讀並理解的讀者。       紅黑樹刪除操作請參考 數據結構 - 紅黑樹(Red

數據結構 - 紅黑樹Red Black Tree刪除與實現Java

replace ati 轉載 之前 9.png one com 四種 簡單   本篇要講的就是紅黑樹的刪除操作       紅黑樹插入操作請參考 數據結構 - 紅黑樹(Red Black Tree)插入詳解與實現(Java)   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意

[Network Architecture]DPNDual Path Network演算法(轉)

https://blog.csdn.net/u014380165/article/details/75676216 論文:Dual Path Networks 論文連結:https://arxiv.org/abs/1707.01629 程式碼:https://github.com/cypw/DPN

紅黑樹Red Black Tree刪除與實現Java

  本篇要講的就是紅黑樹的刪除操作   紅黑樹的刪除是紅黑樹操作中比較麻煩且比較有意思的一部分。   在此之前,重申一遍紅黑樹的五個定義: 1. 紅黑樹的節點要不是黑色的要不是紅色的     2. 紅黑樹的根節點一定是黑色的     3. 紅黑樹的所有葉子節點都是黑色的(注意:紅黑樹的葉子節點指Nil節點

Spring Cloud系列二十四 路由Finchley.RC2版本

傳統路由配置 傳統路由配置就是不需要依賴服務發現機制,通過在配置檔案中具體指定每個路由表示式與服務例項的對映關係來實現API閘道器對外請求的路由。 單例項配置 通過zuul.routes.<route>.path與zuul.routes.<route&

xtrabackup壓縮備份多執行緒備份lz4,pigz

常用備份: 目前較新的:percona-xtrabackup-2.4.11-1.el6.x86_64.rpm 配置percona的yum源。 yum install epel-release yum install libev qpress yum install perl