C++:两个单独的函数在嵌套时返回不同的结果?
C++: Two separate functions return a different result when nested?
我试图将十六进制编码的字符串转换为包含解码字符串的const char*缓冲区。 为此,我有一个函数(string hex_decode(string hex_input)
)来获取字符串并对其进行解码。
在对函数本身进行了几次测试后,我尝试了以下调用:
const char* hex_decoded_c_str = hex_decode(input).c_str();
并看到它返回了完全的胡言乱语! 为了调试问题,我将其分解为两个语句,如下所示:
string hex_decoded_string = hex_decode(input);
const char* hex_decoded_c_str = hex_decoded_string.c_str();
这次效果很好!
我很困惑,有谁知道是什么会导致这样的事情?
string hex_decode(string hex_input)
返回一个临时string
对象。c_str()
返回指向该字符串对象的私有部分的指针。一旦临时死亡(在完整表达式的末尾),该指针将指向无法访问的内存。这就是所谓的未定义行为。
若要解决此问题,请将返回值复制到本地string
对象中,或者通过将临时值绑定到const string&
引用来延长临时对象的生存期。c_str()
返回值的有效性与调用它的对象的生存期相关联。Abidance 不能由编译器、库或运行时强制执行。这是开发人员需要确保的。
有关参考,请参阅生存期。
string hex_decode(string hex_input)
的原型说一个新的字符串对象总是由hex_decode
返回。
标准第12.2#3
段规定:
临时对象在计算(词法上)包含创建它们的点的完整表达式的最后一步被销毁。
此外,c_str()
返回指向字符串对象内部内容的指针。
在阅读c_str()
和data()
的文档(现在执行相同的功能)时,您可以从这一行中推断出来(请参阅此处或21.4.7.1#1
):
c_str() + i == &operator[](i)
每个i in [0, size()]
。
因此:
一旦c_str()
结束,就会有;
,hex_decode()
返回的临时字符串必须被销毁。在销毁过程中,它会释放底层字符数组。
但是,要保留字符数组,无需复制临时字符串。12.2#4,5
:
在两种情况下,临时被摧毁的时间点与完整表达的结束点不同。第二个上下文是当引用绑定到临时时。
因此,您只需将 const 引用绑定到临时对象并保存在复制构造函数调用中:
const string & hex_decoded_string = hex_decode(input);
const char* hex_decoded_c_str = hex_decoded_string.c_str();
const char* hex_decoded_c_str = hex_decode(input).c_str();
您正在引用string
临时对象的内部表示形式(返回值),当hex_decode(input)
超出范围时,该值在c_str()
调用后立即无效。
使用另一种方法,复制string
对象,使该引用在您的范围内有效。
c_str()
方法返回的指针在实例被销毁后std::string
无效。
- 嵌套 if 中没有返回评估
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 受保护的嵌套结构不能用作派生外部类中的返回类型?
- 用于返回嵌套类类型的作用域解析运算符
- 返回自身内部的双重嵌套类的成员函数,该类继承自从自身继承的类
- 访问range_expression中的嵌套元素会返回不完整的映射(段错误)
- 在返回语句中嵌套条件运算符
- 如何在模板类中使用嵌套的结构/类类型作为返回值
- 无效的协变返回类型,嵌套类C
- C++:两个单独的函数在嵌套时返回不同的结果?
- 嵌套模板类返回类型在 C++ 中的头文件中函数返回类型的语法
- C++嵌套类函数返回类型和命名空间
- C 嵌套模板返回类型
- 在C++中,是否存在将结束父函数的嵌套函数的返回
- 按值返回向量,并在C++中嵌套多个函数
- 返回嵌套类的对象
- 如何返回嵌套在其他包中的模板包
- C++如何返回嵌套类的数组类成员
- 如何从方法返回嵌套类指针
- 返回嵌套模板的模板方法的签名会导致编译错误