C++98 字符串连接与 c_str() 返回 [duplicate]

C++98 string concatenation with c_str() return [duplicate]

提问人:Ethan G. 提问时间:9/17/2023 最后编辑:Ethan G. 更新时间:9/17/2023 访问量:118

问:

我想通过在what()上返回字符串之前连接字符串来创建一个自定义异常。我知道其他方法可以实现想要的结果,我只是想了解为什么以下 3 段代码的行为不同。

class InvalidFormat : public std::exception
{
    private:
        std::string _exceptionValue;
    public:
        InvalidFormat(std::string str);
        const char *what() const throw();
};

InvalidFormat::InvalidFormat(std::string str) : _exceptionValue(str) {}

const char *InvalidFormat::what() const throw() {
return ("Format is invalid => " + _exceptionValue).c_str();}
//doesn't output anything
InvalidFormat::InvalidFormat(std::string str) : _exceptionValue(str) {}

const char *InvalidFormat::what() const throw() {
return std::string("Format is invalid => ").assign(_exceptionValue).c_str();}
//outputs random data
InvalidFormat::InvalidFormat(std::string str) : _exceptionValue("Format is invalid => " + str) {}

const char *InvalidFormat::what() const throw() {
return _exceptionValue.c_str();}
//outputs is correct
C++ 字符串 C++98

评论

0赞 tkausl 9/17/2023
您将返回指向局部(临时)变量的指针。
0赞 Nathan Pierson 9/17/2023
看看c_str实际上做了什么。它返回指向对象的基础存储的指针。如果被破坏,你就会留下一个悬空的指针。std::stringstd::string

答:

2赞 YSC 9/17/2023 #1

以下调用一个临时的,其生命在完整表达式(在 ):c_str()std::string ;

return ("Format is invalid => " + _exceptionValue).c_str(); // UB-prone

返回时,返回的指针指向释放和消失的内存,这是未定义的行为。这再好不过了:InvalidFormat::what()

return std::string("Format is invalid => ").assign(_exceptionValue).c_str(); // UB-prone

如果要返回指向它的非拥有指针,则必须存储串联的结果:

InvalidFormat::InvalidFormat(std::string str)
    : _exceptionValue("Format is invalid => " + str)
{}

const char *InvalidFormat::what() const throw()
{
    return _exceptionValue.c_str(); // OK
}

评论

0赞 YSC 9/17/2023
此外,它还避免了在异常处理代码;)中引发异常
1赞 Retired Ninja 9/17/2023
我们需要一个短语来形容这一点,比如异常开始。不久前,我们有一个崩溃处理程序,它编写了崩溃的小型转储和日志,然后将其上传到异地进行分析。工作得很好,直到有一天有一个错误,它用数千个转储填满了几台服务器的硬盘驱动器,并淹没了我们的互联网连接,使远程停止变得非常困难。美好时光!:)
0赞 Ethan G. 9/17/2023
对不起,编辑晚了。我花了一段时间才明白,但我现在明白了。谢谢