C/C++:string.c_str()

本文探讨了C++中string类的c_str()方法的正确使用方式,强调了临时对象和常量指针返回值的特点,并提供了避免潜在问题的建议。

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

C/C++:string.c_str()

今天忽然想起之前的一个小问题:

string.c_str()返回值失效的问题。

关于string.c_str()我个人认为,能多快将其拷贝到一个安全的地方,就尽快将其拷贝吧!

题外话:

其实例如Lua对C的接口中:lua_pushstring (lua_State *L, const char *s)中,就是把字符串s拷贝到栈上,然后返回。

在这里就类似strcpy等将c_str()的内容拷贝出来了,也就“放心了”!

请看如下代码:

string foo()
{
    string s_subfun = "hello, world!";
    return s_subfun;
}

int main()
{
    string s_mainfun = foo();
    return 0;
}

注意,实际上涉及到了三个string对象:

1.s_subfun;
2.s_mainfun;
3.是在foo函数返回时,还会创建一个新的临时对象。

恩,上面要注意第三点,是个临时对象。


如何使用c_str()最保险?

就如同上面的Code一样:

string s_mainfun = foo();

关键是要有一个自己声明的对象来接收foo()返回的值(姑且这么叫吧)。

用s_mainfun来接收了foo()返回的值。

以下使用是有问题的:

string foo()
{
    string s_subfun = "hello, world!";
    return s_subfun;
}

int main()
{
    const char *s = (foo() + "test1280").c_str();
    cout<<s<<endl;
    return 0;
}

我这里虽然能正常输出,但是我认为其极有可能出问题(事实上就是会出问题)。

因为在+的地方实际是新构建了一个临时对象,然后对其进行c_str()调用,然后返回c_str()的值,然后:

这个临时变量析构,但是是在啥时候析构?能保证一定在当前的栈调用完毕时才析构吗?不知道!

但是不论如何,有两条准则是很重要的:

1.在调用c_str()时,注意其对象的状态,是个临时变量还是个局部变量?

2.调用c_str()后,尽可能快地用strcpy等拷贝函数将其拷贝到一个自己“放心”的地方,这不就是君子不立危墙之下吗?

还有几点需要说下。

(1)

string.c_str()返回的是一个const类型值,你说你将其强制转换成非const然后再操作是个啥意思?

int main()
{
    string str = "test1280";
    char *s = (char *)str.c_str();
    cout<<str<<endl;
    s[0] = 'n';
    cout<<str<<endl;
}

Output:

test1280
nest1280

(2)

对字符串的修改可能改变c_str()返回值指向的字符串的内容。

int main()
{
    string str = "test1280";
    const char *s = str.c_str();
    cout<<s<<endl;
    str[2] = 'x';
    cout<<s<<endl;
}

Output:

test1280
text1280

还是那句话:要尽可能快地用strcpy等拷贝c_str()指向的字符串到咱自己地盘,这才放心!

你不知道(记不清),啥时候你就不小心改了字符串string了,而这个有可能影响c_str()指向的字符串的值。

Reference:

c_str() 获得的指针可能被下列行为非法化:

传递给任何非标准库函数字符串的非 const 引用,或
在字符串上调用非 const 成员函数,包括 operator[]at()front()back()begin()rbegin()end()rend() 。

通过 c_str() 写入字符数组是未定义行为。

回归原主题:

对c_str()的使用,要注意其对象的状态,是临时变量还是局部变量?

能确定c_str()后,要尽可能将其复制出来,万一你不小心改变了对象的值,会导致c_str()指向的字符数组内容发生改变~失效!

参考资料:

1.http://blog.youkuaiyun.com/nemo2011/article/details/19921605
2.https://my.oschina.net/ioslighter/blog/361046
3.http://blog.youkuaiyun.com/wangshubo1989/article/details/50286985
4.http://blog.youkuaiyun.com/u013682388/article/details/39547773

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值