標準C 類string的記憶體共享和Cop

2021-07-05 15:48:49 字數 2552 閱讀 5520

標準c++類std::string的

記憶體共享和copy-on-write技術

陳皓scott meyers

在《more effective c++

》中舉了個例子,不知你是否還記得?在你還在上學的時候,你的父母要你不要看電視,而去複習功課,於是你把自己關在房間裡,做出一副正在複習功課的樣子,其實你在幹著別的諸如給班上的某位女生寫情書之類的事,而一旦你的父母出來在你房間要檢查你是否在複習時,你才真正撿起課本看書。這就是「拖延戰術」,直到你非要做的時候才去做。

當然,這種事情在現實生活中時往往會出事,但其在程式設計世界中搖身一變,就成為了最有用的技術,正如

c++中的可以隨處宣告變數的特點一樣,

scott meyers

推薦我們,在真正需要乙個儲存空間時才去宣告變數(分配記憶體),這樣會得到程式在執行時最小的記憶體花銷。執行到那才會去做分配記憶體這種比較耗時的工作,這會給我們的程式在執行時有比較好的效能。必竟,

20%的程式執行了

80%的時間。

當然,拖延戰術還並不只是這樣一種型別,這種技術被我們廣泛地應用著,特別是在作業系統當中,當乙個程式執行結束時,作業系統並不會急著把其清除出記憶體,原因是有可能程式還會馬上再執行一次(從磁碟把程式裝入到記憶體是個很慢的過程),而只有當記憶體不夠用了,才會把這些還駐留記憶體的程式清出。

寫時才拷貝(

copy-on-write

)技術,就是程式設計界「懶惰行為」——拖延戰術的產物。舉個例子,比如我們有個程式要寫檔案,不斷地根據網路傳來的資料寫,如果每一次

fwrite

或是fprintf

都要進行乙個磁碟的

i/o操作的話,都簡直就是效能上巨大的損失,因此通常的做法是,每次寫檔案操作都寫在特定大小的一塊記憶體中(磁碟快取),只有當我們關閉檔案時,才寫到磁碟上(這就是為什麼如果檔案不關閉,所寫的東西會丟失的原因)。更有甚者是檔案關閉時都不寫磁碟,而一直等到關機或是記憶體不夠時才寫磁碟,

unix

就是這樣乙個系統,如果非正常退出,那麼資料就會丟失,檔案就會損壞。

呵呵,為了效能我們需要冒這樣大的風險,還好我們的程式是不會忙得忘了還有一塊資料需要寫到磁碟上的,所以這種做法,還是很有必要的。

在我們經常使用的

stl標準模板庫中的

string

類,也是乙個具有寫時才拷貝技術的類。

c++曾在效能問題上被廣泛地質疑和指責過,為了提高效能,

stl中的許多類都採用了

copy-on-write

技術。這種偷懶的行為的確使使用

stl的程式有著比較高要效能。

這裡,我想從

c++類或是設計模式的角度為各位揭開

copy-on-write

技術在string

中實現的面紗,以供各位在用

c++進行類庫設計時做一點參考。

在講述這項技術之前,我想簡單地說明一下

string

類記憶體分配的概念。通過常,

string

類中必有乙個私有成員,其是乙個

char*

,使用者記錄從堆上分配記憶體的位址,其在構造時分配記憶體,在析構時釋放記憶體。因為是從堆上分配記憶體,所以

string

類在維護這塊記憶體上是格外小心的,

string

類在返回這塊記憶體位址時,只返回

const char*

,也就是唯讀的,如果你要寫,你只能通過

string

提供的方法進行資料的改寫。

由表及裡,由感性到理性,我們先來看一看

string

類的copy-on-write

的表面特徵。讓我們寫下下面的一段程式:

#include

#include

using namespace std;

main()

這個程式的意圖就是讓第二個

string

通過第乙個

string

構造,然後列印出其存放資料的記憶體位址,然後分別修改

str1

和str2

的內容,再查一下其存放記憶體的位址。程式的輸出是這樣的(我在

vc6.0

和g++ 2.95

都得到了同樣的結果):

> g++ -o stringtest stringtest.cpp

> ./stringtest

sharing the memory:

str1's address: 343be9

str2's address: 343be9

after copy-on-write:

str1's address: 3407a9

str2's address: 343be9

從結果中我們可以看到,在開始的兩個語句後,

str1

和str2

存放資料的位址是一樣的,而在修改內容後,

str1

的位址發生了變化,而

str2

的位址還是原來的。從這個例子,我們可以看到

string

類的copy-on-write

技術。

C 標準庫 (string 類)

一 成員函式 二 非成員有關的全域性函式 三 例項 感謝閱讀!其中的string是以char作為模板引數的模板類例項,把字串的記憶體管理責任由string負責而不是由程式設計者負責,大大減輕了c語言風格的字串的麻煩 std basic string提供了大量的字串操作函式,如比較 連線 搜尋 替換 ...

C 的標準string類操作整理

1,定義和構造初始化 測試如下 include include using namespace std int main string str5 ch music roly poly string str6 ch music roly poly string str7 ch music,4 roly...

共享記憶體操作類 c

共享記憶體操作類 using system using system.collections.generic using system.text using system.runtime.interopservices namespace sharememlib sharemem 初始化共享記憶體 ...