引用計數的寫時拷貝

2021-08-03 20:50:34 字數 1801 閱讀 8683

首先我們需要知道什麼是寫時拷貝,通俗的說,就是寫的時候再拷貝。那到底什麼才是寫時拷貝呢?

舉乙個很簡單的例子,就是建立乙個string類的物件,然後用這個物件再拷貝出多個物件,當然指標也會拷貝過去,造成多個物件指向同一塊空間,當對某個物件進行讀操作時,不會發生什麼問題,但當需要對某個物件進行寫操作時,就會出現修改某個物件導致所有物件都會跟著一塊修改,但這並不是我們所期待帶的,我們希望只修改某乙個物件,為了解決此問題我們引入引用計數的寫時拷貝,當某個物件需要進行寫操作時,我們就重新開闢一段空間進行寫操作,從而不影響其他物件的內容。下面**展示:

淺拷貝:

#includeusing namespace std;

class string

string(const string& s)

~string() }

private:

char* _str;

};int main()

除錯視窗:

由上圖除錯視窗我們發現,3個物件指向同一塊空間,析構時同一塊空間會析構3次,所以出現問題。所以,引入引用計數的寫時拷貝。

方案一:我們為每個物件新增乙個計數器。

引入引用計數:

#includeusing namespace std;

class string

//s2(s1)

string(const string& s)

:_str(s._str)

//s2=s1

s2 是否指向同一塊空間

//2.減減s2指向的引用計數,如果s2 是最後乙個管理物件,則釋放

string& operator = (const string& s)

_str = s._str;

_refcountptr = s._refcountptr;

(*_refcountptr)++;

} return *this;

} ~string() }

private:

char* _str;

int* _refcountptr;

};int main()

除錯視窗:

雖然,這個方法解決了淺拷貝析構時出現的問題,但卻存在記憶體碎片問題。

方案二:開闢空間,前面4個位元組為計數器,剩下的空間為_str所指的內容的空間。

#includeusing namespace std;

class string

string(const string& s)

:_str(s._str)

string& operator =(const string& s)

}return *this;

}char& operator(size_t index)

}~string()

}private:

int& _getrefcount(char* ptr)

char* _str;

};

具體如下圖:

這樣不但解決了記憶體碎片問題,而且效率也比進行深拷貝時高。

C 引用計數寫時拷貝

寫時拷貝技術原理 寫時拷貝技術是通過 引用計數 實現的,在分配空間的時候多分配4個位元組,用來記錄有多少個指標指向塊空間,當有新的指標指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數減一,直到引用計數減為0時才真的釋放掉這塊空間。當有的指標要改變這塊空間的值時,再為這個指標重新分配自己的空...

string類的寫時拷貝與引用計數

由於淺拷貝使多個物件共用一塊記憶體位址,呼叫析構函式時導致一塊記憶體被多次釋放,導致程式奔潰。實現string類的時候通常顯示的定義拷貝建構函式和運算子過載函式。由於釋放記憶體空間,開闢記憶體空間時花費時間,因此,在我們不需要寫,只是讀的時候就可以不用新開闢記憶體空間,就用淺拷貝的方式建立物件,當我...

C 拷貝 引用計數

通常,我們會按如下方式書寫拷貝建構函式 class lif 預設建構函式 lif const lif l lif l.lif 拷貝建構函式 private int lif 這是正確的。但是,如果資料成員包含指標型別的話,這種寫法就很危險了。class lif 為lif動態分配記憶體 lif cons...