std::string与char*之临时缓冲区

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生效了。

你可能感兴趣的:(C++)