C++ 奇怪的 string/char* 异常行为

C++ Weird string/char* exception behaviour

这是我的异常代码:

class OptionNotFoundError: public std::exception {
public:
    OptionNotFoundError(std::string option, int position) throw()
        : option(option), position(position) {}
    OptionNotFoundError(char option_, int position) throw()
        : position(position) { option.push_back(option_); }

    virtual ~OptionNotFoundError() throw() {}

    virtual const char* what() const throw() {
        std::string what_str = "Option '" + option + "' not found in position " + std::to_string(position);
        std::cout << what_str.c_str() << std::endl;
        return what_str.c_str();;
    }

    std::string option;
    int position;
};

当抛出异常时,这是我在终端中得到的:

terminate called after throwing an instance of 'Args::OptionNotFoundError'
Option 'c' not found in position 1
  what():  

所以 cout 工作正常,但是……不是 return。如果我使用 return "smth" 它工作正常。

更奇怪:如果我将 what_str 定义替换为

std::string what_str = "test";

我明白了

terminate called after throwing an instance of 'Args::OptionNotFoundError'
test
  what():  x�zL�

同样,cout<< 工作正常。但是 return... 没那么多。这是编码错误吗?

    return what_str.c_str();;

c_str() returns 指向 std::string.

内部内容的指针

此指针仅在

之前有效
  1. std::string 对象被销毁。

  2. std::string 对象被修改。

当您的函数 returns.

时,从中获取此 c_str() 指针的 std::string 对象被销毁

这会导致未定义的行为。

const char * 你的函数 returns 无效。它指向被销毁对象的内部内容。

对于第一种情况,注意what_strwhat()内部的一个局部变量,离开函数作用域后会被销毁,返回的指针变为悬空,对其取消引用会导致 UB。

对于第二种情况,返回 "smth" 可以正常工作,因为 "smth" 是一个 const char[5],它是一个 string literal

String literals have static storage duration, and thus exist in memory for the life of the program.

对于第3种情况,

if i replace what_str definition with

std::string what_str = "test";

不行,因为what_str还是本地的std::string,问题和第一种一样。