C++:两个单独的函数在嵌套时返回不同的结果?

C++: Two separate functions return a different result when nested?

本文关键字:返回 嵌套 结果 函数 两个 C++ 单独      更新时间:2023-10-16

我试图将十六进制编码的字符串转换为包含解码字符串的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无效。