- C和C++安全編碼(原書第2版)
- (美)Robert C.Seacord
- 458字
- 2020-10-30 17:56:42
2.4.4 C++ std::basic_string
此前我們描述了一個常見的編程漏洞,它使用C++的提取操作符operator>>從標準的std::cin iostream對象讀入輸入,并寫入一個字符數組。雖然設置字段寬度消除了緩沖區溢出漏洞,但它沒有解決截斷的問題。此外,達到最大字段寬度且輸入流中剩余的字符被提取操作符的下一次調用使用時,可能會導致意想不到的程序的行為。
C++程序員可以選擇使用在ISO/IEC 14882中定義的標準的std::string類。std::string類是std::basic_string模板在char類型上的一個特化。std::wstring類是st::basic_string模板在wchar_t類型上的一個特化。
basic_string類代表一個字符序列。它支持序列操作以及字符串操作,如搜索和串聯,并由字符類型參數化。
basic_string類使用一種動態方法,按需要為字符串分配內存—這意味著在所有的情況下,size()<=capacity()。basic_string類很方便,因為語言直接支持這個類。此外,許多現有的庫已經使用這個類,這簡化了集成工作。
basic_string類實現了“由被調用者分配,由被調用者釋放”的內存管理策略。這是最安全的方法,但它僅支持C++。因為basic_string管理內存,所以調用者并不需要擔心內存管理的細節。例如,字符串串聯的簡單處理如下所示。
1 string str1 = "hello, "; 2 string str2 = "world"; 3 string str3 = str1 + str2;
在其內部,basic_string使用動態分配內存的方法,緩沖區總是自動調整大小以容納所需的數據,通常是通過調用realloc()函數。這些方法擴展性優于對應的C函數,而且不丟棄超出的數據。
下面的程序顯示了一個解決方案,從std::cin提取字符到一個std::string中,它使用一個std::string對象來代替一個字符數組:
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 }
這個程序簡單而優雅,處理了緩沖區溢出和字符串截斷問題,并且其行為方式是可預見的。你還有什么想要的呢?
basic_string類比以空字符結尾的字節串更不容易有安全漏洞,但編碼錯誤仍然可能導致的安全漏洞。使用basic_string類時,應考慮的領域之一是迭代器。可以使用迭代器遍歷一個字符串的內容,如下所示。
1 string::iterator i; 2 for (i = str.begin(); i != str.end(); ++i) { 3 cout << *i; 4 }
- LaTeX Cookbook
- Learning Java Functional Programming
- Getting Started with React
- Linux C/C++服務器開發實踐
- Visual Basic程序設計教程
- 深入淺出Windows API程序設計:編程基礎篇
- PhpStorm Cookbook
- 基于Swift語言的iOS App 商業實戰教程
- 軟件測試實用教程
- 基于ARM Cortex-M4F內核的MSP432 MCU開發實踐
- .NET Standard 2.0 Cookbook
- Mudbox 2013 Cookbook
- Visual Basic 程序設計實踐教程
- HTML5移動前端開發基礎與實戰(微課版)
- Java高并發編程詳解:深入理解并發核心庫