小心使用临时string对象的c_str()值

本文探讨了C++代码中直接使用临时对象的c_str()方法可能导致的问题,解释了为什么这样做会导致c_str()返回空值,并提供了两种避免此错误的方法。此外,还详细介绍了c_str()函数的陷阱,包括修改字符串对象后c_str()返回值的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这篇链接http://blog.youkuaiyun.com/while0/article/details/26291855  里看到这样的代码

const char* file_path = FileUtils::getInstance()->fullPathForFilename("hello.json").c_str();
log("external file path = %s",file_path);
rapidjson::Document d1;
std::string contentStr = FileUtils::getInstance()->getStringFromFile(file_path);
d1.Parse<0>(contentStr.c_str());
//打印JSon文件的内容
printf("%s\n",contentStr.c_str());

粗看这个代码,似乎没有问题,实际上有大问题,在我的xcode里运行,第4行的file_path变成了空字符串,为啥?

还有这个例子:

string getString()
{
    return "just a test";
}
void test()
{
    const char *pc = getString().c_str();
    cout<<pc<<endl;
}

输出结果会为空。(有的编译器可能没问题)

两段代码的相同点是都存在没有将返回结果赋给string对象再取c_str值,而是直接通过返回的临时对象取c_str值,这样得到的c_str赋值在临时string对象析构后变为空值。

有两种比较可行的解决方法。

1.不要直接返回临时对象的指针,将临时对象先赋值给一个局部对象,再获取其指针。这样,将上例改写为

void test()
{    
    string str = getString();    
    const char *pc = str.c_str();
    cout<<pc<<endl;
}

2.如果要使用临时对象的指针,将所有的使用放到一个语句里进行。这样,将上例改写为

void test()
{
    cout<<getString().c_str()<<endl;
}


关于c_str(),还有下面的陷阱:

int main(){ 
    string greet("Hello, world");        
    string hi(greet);        
    char *ptr = (char *)hi.c_str();        
    ptr[0] = 'h';        
    cout << hi << endl;        
    cout << greet << endl;
}
int main() { 
    string s = "Alexia"; 
    const char *str = s.c_str(); 
    cout << str << endl; 
    s[1] = 'm'; 
    cout << str << endl; 
    return 0; 
}

可以试试看有怎样的输出结果。

参考:

http://www.cnblogs.com/studynote/p/3476993.html

http://blog.youkuaiyun.com/song_hui_xiang/article/details/8830000

http://blog.sina.com.cn/s/blog_4e0c21cc010095hf.html 

转载于:https://my.oschina.net/ioslighter/blog/361046

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值