官术网_书友最值得收藏!

2.4.4 C++ std::basic_string

此前我們描述了一個常見的編程漏洞,它使用C++的提取操作符operator>>從標(biāo)準(zhǔn)的std::cin iostream對象讀入輸入,并寫入一個字符數(shù)組。雖然設(shè)置字段寬度消除了緩沖區(qū)溢出漏洞,但它沒有解決截斷的問題。此外,達到最大字段寬度且輸入流中剩余的字符被提取操作符的下一次調(diào)用使用時,可能會導(dǎo)致意想不到的程序的行為。

C++程序員可以選擇使用在ISO/IEC 14882中定義的標(biāo)準(zhǔn)的std::string類。std::string類是std::basic_string模板在char類型上的一個特化。std::wstring類是st::basic_string模板在wchar_t類型上的一個特化。

basic_string類代表一個字符序列。它支持序列操作以及字符串操作,如搜索和串聯(lián),并由字符類型參數(shù)化。

basic_string類使用一種動態(tài)方法,按需要為字符串分配內(nèi)存—這意味著在所有的情況下,size()<=capacity()。basic_string類很方便,因為語言直接支持這個類。此外,許多現(xiàn)有的庫已經(jīng)使用這個類,這簡化了集成工作。

basic_string類實現(xiàn)了“由被調(diào)用者分配,由被調(diào)用者釋放”的內(nèi)存管理策略。這是最安全的方法,但它僅支持C++。因為basic_string管理內(nèi)存,所以調(diào)用者并不需要擔(dān)心內(nèi)存管理的細節(jié)。例如,字符串串聯(lián)的簡單處理如下所示。


1  string str1 = "hello, ";
2  string str2 = "world";
3  string str3 = str1 + str2;

在其內(nèi)部,basic_string使用動態(tài)分配內(nèi)存的方法,緩沖區(qū)總是自動調(diào)整大小以容納所需的數(shù)據(jù),通常是通過調(diào)用realloc()函數(shù)。這些方法擴展性優(yōu)于對應(yīng)的C函數(shù),而且不丟棄超出的數(shù)據(jù)。

下面的程序顯示了一個解決方案,從std::cin提取字符到一個std::string中,它使用一個std::string對象來代替一個字符數(shù)組:


01  #include <iostream>
02  #include <string>
03  using namespace std;
04
05  int main(void) {
06    string str;
07
08    cin >> str;
09    cout << "str 1: " << str << '\n';
10  }

這個程序簡單而優(yōu)雅,處理了緩沖區(qū)溢出和字符串截斷問題,并且其行為方式是可預(yù)見的。你還有什么想要的呢?

basic_string類比以空字符結(jié)尾的字節(jié)串更不容易有安全漏洞,但編碼錯誤仍然可能導(dǎo)致的安全漏洞。使用basic_string類時,應(yīng)考慮的領(lǐng)域之一是迭代器。可以使用迭代器遍歷一個字符串的內(nèi)容,如下所示。


1  string::iterator i;
2  for (i = str.begin(); i != str.end(); ++i) {
3    cout << *i;
4  }

主站蜘蛛池模板: 连州市| 盱眙县| 凤阳县| 中超| 含山县| 清远市| 鹤庆县| 商洛市| 三亚市| 福州市| 涞水县| 浑源县| 新蔡县| 榕江县| 永宁县| 商洛市| 广水市| 鸡西市| 麟游县| 霍林郭勒市| 梅河口市| 望江县| 诸暨市| 汽车| 新化县| 建平县| 清涧县| 镇巴县| 定远县| 金川县| 抚松县| 尼玛县| 阳泉市| 鹰潭市| 外汇| 绥宁县| 伊通| 鄂尔多斯市| 江都市| 都江堰市| 建平县|