寫時拷貝COW(copy-on-write)
阿新 • • 發佈:2017-09-04
display 語句 namespace div str pre style -a [0 寫時拷貝技術是通過"引用計數"實現的,在分配空間的時候多分配4個字節,用來記錄有多少個指針指向塊空間,當有新的指針指向這塊空間時,引用計數加一,當要釋放這塊空間時,引用計數減一(假裝釋放),直到引用計數減為0時才真的釋放掉這塊空間。當有的指針要改變這塊空間的值時,再為這個指針分配自己的空間(註意這時引用計數的變化,舊的空間的引用計數減一,新分配的空間引用計數加一)。
#include<iostream> #include<new.h> #include<string> using namespace std; //1解決內存泄漏 //2編寫賦值語句 //3寫時拷貝 class String; ostream& operator<<(ostream &out, const String &s); ///////////////////////////////////////////////////////////////////// class String_rep { friend class String; friend ostream& operator<<(ostream &out, const String &s); private: String_rep(const char *str = "") : use_count_(0) { if (str == NULL) { data = new char[1]; data[0] = ‘\0‘; } else { data = new char[strlen(str) + 1]; strcpy(data, str); } } String_rep(const String_rep &rep) { this->data = rep.data; } String_rep& operator=(const String_rep &rep) { this->data = rep.data; } ~String_rep() { if (data != NULL) { delete[]data; data = NULL; } } public: void increment() { ++use_count_; } void decrement() { //引用計數為0,釋放共享內存 if (--use_count_ == 0) delete this; } private: char *data; int use_count_; }; ////////////////////////////////////////////////////// class String { friend ostream& operator<<(ostream& out, const String &s); public: String(const char *str = "") :rep(new String_rep(str)) { rep->increment(); } String(const String &s) { rep = s.rep; rep->increment(); } String& operator=(const String &s) { if (&s != this) { this->rep->decrement(); //原有共享內存中的引用計數減一 this->rep = s.rep; this->rep->increment(); //現有引用計數加一 } return *this; } ~String() { //String析構一次,引用計數減一 rep->decrement(); } public: void to_upper(); String& operator+=(const String &str); private: String_rep *rep; }; ///////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream &out, const String &s) { out << s.rep->data; return out; } //創建新的共享內存原來共享內存中值一樣,然後再修改 void String::to_upper() { String *newStr = new String(this->rep->data); this->rep->decrement(); this->rep = newStr->rep; this->rep->increment(); char *str = this->rep->data; while (*str != ‘\0‘) { *str -= 32; ++str; } delete newStr; } String& String::operator+=(const String &str) { char *ch = new char[strlen(str.rep->data) + strlen(this->rep->data) + 1]; strcpy(ch,this->rep->data); strcat(ch, str.rep->data); this->rep->decrement(); String_rep *s = new String_rep(ch); this->rep = s; this->rep->increment(); return *this; } int main() { String s("abc"); String s1; s1 = s; // String s2("xyz"); String s3(s); s2.to_upper(); s3 += s2; cout << s2 << endl; cout << s3 << endl; return 0; }
寫時拷貝COW(copy-on-write)