std::string使用异常:调用getbbb后aval值被意外覆盖
问题分析与解决
问题根源
你这段代码的核心问题是悬空指针引发的未定义行为:
getaaa()返回的是临时std::string对象,const char * aval = getaaa().c_str();这条语句执行完毕后,这个临时对象会立刻被销毁。c_str()返回的指针指向临时string内部的字符数组,临时对象销毁后,该指针就变成了悬空指针,指向的内存已被释放,属于非法访问区域。- 调用
getbbb()时,新生成的临时std::string对象大概率复用了之前临时对象占用的内存空间,导致悬空指针aval指向的内容被"bbb"覆盖,最终第二次打印出错误结果。
修复方案
有两种简单可靠的修复方式:
方式1:保留持久化的std::string对象
把临时string保存到局部变量中,让它的生命周期覆盖整个指针使用过程:
#include <string> #include <cstdio> std::string getaaa() { return std::string("aaa"); } std::string getbbb() { return std::string("bbb"); } int main(int argc, char * argv[]) { std::string a_str = getaaa(); // 保存临时对象到局部变量,延长生命周期 const char * aval = a_str.c_str(); printf("test A aval: \"%s\"\n", aval); getbbb(); printf("test B aval: \"%s\"\n", aval); return 0; }
方式2:直接使用std::string输出(更推荐)
避免使用c_str()的指针,直接操作std::string对象,从根源上杜绝悬空指针问题:
#include <string> #include <iostream> std::string getaaa() { return std::string("aaa"); } std::string getbbb() { return std::string("bbb"); } int main(int argc, char * argv[]) { std::string aval = getaaa(); std::cout << "test A aval: \"" << aval << "\"\n"; getbbb(); std::cout << "test B aval: \"" << aval << "\"\n"; return 0; }
验证结果
修复后运行程序,会得到预期输出:
test A aval: "aaa" test B aval: "aaa"
内容的提问来源于stack exchange,提问作者Sullivan
相关产品推荐
相关产品推荐

