std::string::resize() 對緩沖區一些用處
如果需要一個緩沖區來暫存字符串會先定義一個char*的數組來實現
存完后又給string賦值,感覺有點麻煩,尋思有什么方法可以更優雅點
比如如下代碼
1 void CVTString::StrToWStr(std::string& strString, std::wstring& wsString, unsigned int uCodePage) 2 { 3 int len = 0; 4 wchar_t* buffer = nullptr; 5 6 len = MultiByteToWideChar(uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), NULL, NULL); 7 buffer = new wchar_t[len + 1]; 8 MultiByteToWideChar(uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), buffer, len); 9 buffer[len] = L'\0'; 10 wsString = buffer; 11 12 delete[] buffer; 13 }
這個new可不可以去掉呢?這樣的話buffer指針和delete也可以去掉了,性能應該有一丟丟提升
std::string有一個resize方法可以改變string分配的緩沖區大小
同時配合data方法來獲取緩沖區的指針,這樣可以實現一個char*數組效果的緩沖區。
但是注意的是string內部默認是分配了一個較小的緩沖區,如果resize的大小比較小
data方法的指針仍然不變,但是如果resize比較大,data返回的指針會變化
也就是會釋放舊緩沖區,重新分配緩沖區。
這個大小的界限在vc上是16,也就是大于等于16的resize會重新分配緩沖區。
同時也就提醒我們,不要認為data和c_str返回的地址總是不變的。
如果是resize小于當前字符串長度,會直接截斷字符串,也就是在目標長度的緩沖區補0,暫時沒發現會進行重新分配。
resize還有一點,resize的長度默認是不包含字符串結束符號 \0 的,也就是resize(5),實際上會分配6的空間,最后一個字節補0
對于wstring則是補充\0\0
resize的第二個參數是填寫補充的字符,resize(10,'x'),如果比原始字符串長,則會補充x字符,往小resize不會,而且依然會在最后補充結束符。
最終優化的代碼(僅演示,一些錯誤處理沒寫)
1 void CVTString::StrToWStr(std::string& strString, std::wstring& wsString, unsigned int uCodePage) 2 { 3 int charCount = MultiByteToWideChar 4 ( 5 uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), NULL, NULL 6 ); 7 8 if (charCount == 0) return; 9 10 wsString.resize(charCount); 11 MultiByteToWideChar 12 ( 13 uCodePage, NULL, strString.c_str(), static_cast<int>(strString.size()), const_cast<wchar_t*>(wsString.data()), charCount 14 ); 15 }
2024年4月29日 :
不過以上代碼還是有個性能問題的

浙公網安備 33010602011771號