string的拷貝是面試中的經常會被問到的問題,所以,學懂string類是非常重要的。
下面我們先來看一段**:
class
string
else
}string(const
string &s)//拷貝建構函式,相當於系統預設合成
:_pstr(s._pstr){}
string& operator = (const
string& s)//賦值運算子的過載
return *this;
}~string()//析構函式
}private:
char* _pstr;
};void funtest()
int main()
一執行發現程式崩潰了,那麼問題到底出在**呢?對**進行除錯後我們可以發現如下現象:
可以看到,s2和s3的位址是指向同一塊空間的,那在呼叫析構函式時豈不是對一段空間析構了兩次嗎?這裡不止是程式崩潰,還出現了記憶體洩漏。這就是string的經典反例:淺拷貝。面試的時候可千萬別寫出這樣的**哦。
那麼解決這種問題的方案是什麼呢?下面就來介紹:深拷貝
(1)普通版本
class string
else
}string & operator = (const string &s)
return *this;
}~string()
}string(const string &s)
:_pstr(new
char[strlen(s._pstr) + 1])
private:
char *_pstr;
};void funtest()
int main()
除錯結果如下:
此時,s2,s3,s4不再使用同一塊空間,這便解決了淺拷貝中記憶體洩漏以及程式崩潰的問題,深拷貝還有乙個簡潔版,如下:
(2)簡潔版
class string
else
}string(const string &s)
:_pstr(null){}
string &operator = (const string &s)
return *this;
}~string()
}private:
char *_pstr;
};
當我們需要寫的時候才去新開闢記憶體空間。這種方法就是寫時拷貝。這也是一種解決由於淺拷貝使多個物件共用一塊記憶體位址,呼叫析構函式時導致一塊記憶體被多次釋放,導致程式奔潰的問題。這種方法需要用到引用計數:使用int *儲存引用計數;採用所申請的4個位元組空間。
class string
else
}string(const string &s)
:_pstr(s._pstr)
string& operator = (const string &s)
return *this;
}char& operator(size_t index)
return _pstr[index];
}const
char & operator(size_t index)const
friend ostream operator
<
private:
char *_pstr;
int& getcount()
void release()}};
修改 string 資料時,先判斷計數器是否為 0( 0 代表沒有其他物件共享記憶體空間),為 0 則可以直接使用記憶體空間(如上例中的 s2 ),否則觸發寫時拷貝,計數 -1 ,拷貝乙份資料出來修改,並且新的記憶體計數器置 0 ; string 物件析構時,如果計數器為 0 則釋放記憶體空間,否則計數也要 -1 。
寫時拷貝存在的執行緒安全問題
執行緒安全就是多執行緒訪問時,採用了加鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能進行訪問直到該執行緒讀取完,其他執行緒才可使用。不會出現資料不一致或者資料汙染。 執行緒不安全就是不提供資料訪問保護,有可能出現多個執行緒先後更改資料造成所得到的資料是髒資料。
String類,淺拷貝,深拷貝
想要使用c 中的類那麼必須要有它的標頭檔案,include 首先來看下面乙個 這個程式很簡單,但是如果有乙個空指標呢?那麼就需要判斷了,並且用預設值把有引數的string和沒有引數的string合併在一起,那這個程式只需要做下面的改變 既然你的建構函式開闢了一段空間,那麼就需要釋放掉,此時就需要析構...
python面試題 深拷貝與淺拷貝
1.賦值拷貝 2.copy淺拷貝 3.deepcopy深拷貝 import copya 1,2,3,4 賦值拷貝,預設淺拷貝,傳遞物件的引用而已,原始列表改變,被賦值的b也會做相同的改變 b a5 print a,adress id a 1,2,3,4 5 adress 2670537167752 ...
C 淺拷貝和深拷貝(String類)
簡單的來說,淺拷貝 是增加了乙個指標,指向原來已經存在的記憶體。而 深拷貝 是增加了乙個指標,並新開闢了一塊空間 讓指標指向這塊新開闢的空間。淺拷貝 在多個物件指向一塊空間的時候,釋放乙個空間會導致其他物件所使用的空間也被釋放了,再次釋放便會出現錯誤 為了形象化說明什麼是深拷貝和淺拷貝,我們就先寫乙...