深入探究C++ string的內(nèi)部究竟是什么樣的
在C語言中,有兩種方式表示字符串:
- 一種是用字符數(shù)組來容納字符串,例如char str[10] = "abc",這樣的字符串是可讀寫的;
- 一種是使用字符串常量,例如char *str = "abc",這樣的字符串只能讀,不能寫。
兩種形式總是以\0作為結(jié)束標(biāo)志。
C++ string 與它們在C語言中的前身截然不同。首先,也是最重要的不同點(diǎn),C++ string 隱藏了它所包含的字符序列的物理表示。程序設(shè)計(jì)人員不必關(guān)心數(shù)組的維數(shù)或\0方面的問題。
string 在內(nèi)部封裝了與內(nèi)存和容量有關(guān)的信息。具體地說,C++ string 對象知道自己在內(nèi)存中的開始位置、包含的字符序列以及字符序列長度;當(dāng)內(nèi)存空間不足時(shí),string 還會(huì)自動(dòng)調(diào)整,讓內(nèi)存空間增長到足以容納下所有字符序列的大小。
C++ string 的這種做法,極大地減少了C語言編程中三種最常見且最具破壞性的錯(cuò)誤:
- 數(shù)組越界;
- 通過未被初始化或者被賦以錯(cuò)誤值的指針來訪問數(shù)組元紊;
- 釋放了數(shù)組所占內(nèi)存,但是仍然保留了“懸空”指針。
C++ 標(biāo)準(zhǔn)沒有定義 string 類的內(nèi)存布局,各個(gè)編譯器廠商可以提供不同的實(shí)現(xiàn),但必須保證 string 的行為一致。采用這種做法是為了獲得足夠的靈活性。
特別是,C++ 標(biāo)準(zhǔn)沒有定義在哪種確切的情況下應(yīng)該為 string 對象分配內(nèi)存空間來存儲(chǔ)字符序列。string 內(nèi)存分配規(guī)則明確規(guī)定:允許但不要求以引用計(jì)數(shù)(reference counting)的方式實(shí)現(xiàn)。但無論是否采用引用計(jì)數(shù),其語義都必須一致。
C++ 的這種做法和C語言不同,在C語言中,每個(gè)字符型數(shù)組都占據(jù)各自的物理存儲(chǔ)區(qū)。在 C++ 中,獨(dú)立的幾個(gè) string 對象可以占據(jù)也可以不占據(jù)各自特定的物理存儲(chǔ)區(qū),但是,如果采用引用計(jì)數(shù)避免了保存同一數(shù)據(jù)的拷貝副本,那么各個(gè)獨(dú)立的對象(在處理上)必須看起來并表現(xiàn)得就像獨(dú)占地?fù)碛懈髯缘拇鎯?chǔ)區(qū)一樣。例如:
// #include<bits/stdc++.h>
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1("12345");
string s2 = s1;
cout << (s1 == s2) << endl;
s1[0] = '6';
cout << "s1 = " << s1 << endl; // 62345
cout << "s2 = " << s2 << endl; // 12345
cout << (s1 == s2) << endl;
return 0;
}
在 GCC 下的運(yùn)行結(jié)果:
1
s1 = 62345
s2 = 12345
0
只有當(dāng)字符串被修改的時(shí)候才創(chuàng)建各自的拷貝,這種實(shí)現(xiàn)方式稱為寫時(shí)復(fù)制(copy-on-write)策略。當(dāng)字符串只是作為值參數(shù)(value parameter)或在其他只讀情形下使用,這種方法能夠節(jié)省時(shí)間和空間。
不論一個(gè)庫的實(shí)現(xiàn)是不是采用引用計(jì)數(shù),它對 string 類的使用者來說都應(yīng)該是透明的。遺憾的是,情況并不總是這樣。在多線程程序中,幾乎不可能安全地使用引用計(jì)數(shù)來實(shí)現(xiàn)。
到此這篇關(guān)于C++ string的內(nèi)部究竟是什么樣的的文章就介紹到這了,更多相關(guān)C++ string內(nèi)部是什么內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
QT實(shí)現(xiàn)按鈕開關(guān)Form窗體的效果的示例代碼
本文主要介紹了QT實(shí)現(xiàn)按鈕開關(guān)Form窗體的效果的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
C語言中#pragma?pack(1)的用法與注意點(diǎn)
#pragma用于指示編譯器完成一些特定的動(dòng)作,下面這篇文章主要給大家介紹了關(guān)于C語言中#pragma?pack(1)的用法與注意點(diǎn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn)
scandir?函數(shù)用于列舉指定目錄下的文件列表,本文主要介紹了C語言scandir函數(shù)獲取文件夾內(nèi)容的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
C++模擬實(shí)現(xiàn)STL容器vector的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器vector的相關(guān)資料,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下2022-11-11
Visual Studio C++指針靠前靠后的問題全面解析
這篇文章主要介紹了Visual Studio C++指針靠前靠后的問題全面解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
C語言多種方法實(shí)現(xiàn)一個(gè)函數(shù)左旋字符串中K個(gè)字符
這篇文章主要為大家介紹了C語言多種方法實(shí)現(xiàn)一個(gè)函數(shù),可以左旋字符串中K個(gè)字符,文中附含詳細(xì)的示例講解,有需要的朋友可以借鑒參考下2021-10-10
C++用read()和write()讀寫二進(jìn)制文件的超詳細(xì)教程
二進(jìn)制的文件肉眼我們是讀不懂的,如果通過二進(jìn)制的讀寫操作就可以讀懂,下面這篇文章主要給大家介紹了關(guān)于C++用read()和write()讀寫二進(jìn)制文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06

