面試題 String類的淺拷貝 深拷貝 寫時拷貝

2021-07-30 15:14:37 字數 2299 閱讀 1106

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類)

簡單的來說,淺拷貝 是增加了乙個指標,指向原來已經存在的記憶體。而 深拷貝 是增加了乙個指標,並新開闢了一塊空間 讓指標指向這塊新開闢的空間。淺拷貝 在多個物件指向一塊空間的時候,釋放乙個空間會導致其他物件所使用的空間也被釋放了,再次釋放便會出現錯誤 為了形象化說明什麼是深拷貝和淺拷貝,我們就先寫乙...