C++怪异的字符串/char*异常行为



这是我的异常代码:

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 "smth",它可以正常工作。

Weirder:如果我用替换what_str定义

std::string what_str = "test";

我得到

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

同样,cout<<工作良好。但回报…没有那么多。这是某种编码错误吗?

    return what_str.c_str();;

CCD_ 4返回指向CCD_ 5的内部内容的指针。

此指针仅在任一之前保持有效

  1. std::string对象被销毁。

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

当函数返回时,从中获取此c_str()指针的std::string对象将被销毁。

这会导致未定义的行为。

函数返回的const char *无效。它指向一个被破坏对象的内部内容。

对于第一种情况,请注意what_strwhat()内部的局部变量,当它离开函数范围时会被销毁,然后它返回的指针变为悬空,对它的取消引用会导致UB。

对于第二种情况,返回"smth"效果良好,因为"smth"是一个const char[5],它是一个字符串文字

字符串文字具有静态存储持续时间,因此在程序的整个生命周期中都存在于内存中。

对于第三种情况,

如果我用替换what_str定义

std::string what_str = "test";

它不起作用,因为what_str仍然是本地std::string,所以问题与第一种情况相同。

最新更新