我正在用what()方法编写一个异常类。
const char* what() const throw() {
return "test";
}
工作正常,但
const char* what() const throw() {
return (std::string("test")).c_str();
}
似乎会返回一个随机结果。为什么呢?
答案 0 :(得分:13)
std::string("test")
创建临时字符串对象。 c_str
返回指向该临时对象的某个内部存储的指针。函数退出后,这是一个悬空指针 - 它指向无效的内存。
没有办法绕过这个。你要么通过在函数外部声明(并初始化,因为函数是const
)来使你的字符串对象更长寿 - 或者你需要在函数内手动分配堆存储,在那里复制字符串,并返回指向该存储的指针。但是,这很复杂,容易出错,并且违反了函数的约定,因为错误类的用户不希望释放内存。
事实上,这是一个错误类的简单实现(玩具,因为我不知道你的用例),记住这一点:
struct my_logic_error : std::logic_error {
// `std::logic_error` already overrides `what`, we only need to initialise it!
my_logic_error(int errcode) :
std::logic_error{std::string{"Logic error occurred with error code "} +
std::to_string(errcode)} {}
};
假设您从没有这种奢侈的异常类派生,您的代码变得最简单:
struct my_error : std::exception {
my_error(int errcode) :
message{std::string{"Logic error occurred with error code "} +
std::to_string(errcode)} {}
char const* what() const noexcept {
return message.c_str();
}
private:
std::string message;
};
答案 1 :(得分:0)
将字符串值存储在异常类的成员中,并在此成员上返回c_str()。
执行strdup可以工作,但调用者必须释放内存,这不是一种安全的做法。