std::string與char*之臨時緩衝區
阿新 • • 發佈:2019-01-22
c++檔案讀取流程如下:
ifstream ifs(srcFile, ifstream::binary);
if(ifs.is_open())
{
ifs.seekg(0, ifs.end);
long filesize = ifs.tellg();
ifs.seekg (0);
char* fileBuffer = new char[filesize]; //分配記憶體緩衝區
ifs.read(fileBuffer, filesize); //讀取檔案內容到緩衝區
ifs.close();
//do sth. with fileBuffer
delete []fileBuffer; //release memory
}
整個流程中記憶體的分配和讀沒什麼問題。如果需要對fileBuffer的內容做些字串處理相關的工作,因std::string操作比較方便,通常會先把fileBuffer轉化為std::string,然後再刪掉fileBuffer,如下
char* fileBuffer = new char[filesize]; //分配記憶體緩衝區
ifs.read(fileBuffer, filesize); //讀取檔案內容到緩衝區
ifs.close();
std::string strBuffer(fileBuffer);
delete []fileBuffer; //release memory
//do sth. with strBuffer...
這麼做其實也沒什麼問題,風險無非有兩個,一是忘了delete []fileBuffer,二是記憶體緩衝區可能在建立strBuffer時翻了一倍,雖然std::string在設計時考慮到了copy on write,但風險依然是存在的。
為了解決上面若有若無的風險,需要使用c++程式設計中常用的模式RAII即“資源獲取就是初始化”,用物件來管理資源,如下:
std::string strBuffer(filesize, 0);//分配記憶體緩衝區
char* fileBuffer = &*strBuffer.begin(); //獲取分配記憶體緩衝區的首地址
ifs.read(fileBuffer, filesize); //讀取內容到緩衝區
ifs.close();
//do sth. with strBuffer or fileBuffer...
另外,C++11後調整了std::string,收緊了相關許可權,比如:
常量字串必須是const只讀的
char* str = "this is test string"; //wrong
const char* str = "this is a test string"; //right
const char* 物件不能賦值給 char*
std::string str = "this is test string";
char* szStr = str.c_str(); //wrong
char* szStr = str.data(); //wrong
const char* szStr = str.c_str(); //right
const char* szStr = str.data(); //right
如果需要把std::string賦值給char*,即取得std::string物件的可讀寫首地址,需要轉變思路
先獲取首元素,然後對其取地址
std::string str = "this is a string";
char* szStr = &*str.begin();
char* szStr = &str[0];
這樣對szStr的操作也對str生效了。