C++使用c_str给char指针赋值运行结果异常问题求解
问题原因解释
核心诱因:临时对象生命周期导致野指针
std::string::substr() 的返回值是临时std::string对象,C++标准中规定:临时对象的生命周期仅维持到它所在的完整表达式执行结束。
你写的赋值语句:
temp = str.substr(0, str.length()).c_str();
执行流程是:
- 调用
substr生成临时string对象 - 调用临时对象的
c_str()方法拿到指向其内部字符数组的指针,赋值给temp - 整个赋值语句(完整表达式)执行完毕,临时string对象被析构,其管理的内存空间被释放
此时temp就变成了野指针,指向已经被回收的内存空间,后续调用printf(temp)访问非法内存,属于未定义行为,输出乱码是典型的未定义行为表现。
其余两处打印正常的原因
- 第一处
printf(str.substr(0, str.length()).c_str()):临时string对象的生命周期覆盖整个printf调用过程,printf执行完成前临时对象不会被销毁,指向的内存有效,因此打印正常 - 第三处
printf(test):test指向的是字符串常量,存储在程序的静态存储区,生命周期和程序运行周期一致,内存始终有效,因此打印正常
修复方案
如果需要长期持有c_str()返回的指针,需要先把substr的返回值存到一个有名字的、生命周期足够长的string变量中,再调用c_str():
#include <iostream> using namespace std; int main() { string str("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); // 先把substr结果存入命名变量sub_str string sub_str = str.substr(0, str.length()); const char* temp = sub_str.c_str(); printf(sub_str.c_str()); printf(temp); // 此时temp指向sub_str的内部内存,sub_str未销毁,内存有效 const char* test = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; printf(test); return 0; }
只要sub_str还处于作用域内、未被析构,temp指针就可以安全使用。
内容的提问来源于stack exchange,提问作者Gokul Raj V
相关产品推荐
相关产品推荐

