使用相同消息重新引发新异常会导致垃圾输出.为什么?

Rethrowing new exception with same message causes garbage output. Why?

本文关键字:为什么 输出 异常 消息 新异常 新引发      更新时间:2023-10-16

我想捕获异常以进一步指定错误消息,然后使用该扩展消息抛出一个新异常。但是,这会导致垃圾输出。为什么?

这是一个MWE:

#include <iostream>
#include <string>
#include <exception>
class myError : public std::exception
{
private:
std::string m_error;
public:
explicit myError( const std::string& error ) :
m_error { error }
{}
explicit myError( const char* error ) :
m_error { error }
{} 
const char* what() const noexcept override
{
//return m_error.c_str();
return ("My error: " + m_error).c_str();
}
};

int main()
{
try{
try{
throw myError ( "Error message" );
} catch ( const std::exception& e ) {
throw myError( e.what() );
}
} catch ( const std::exception& e ) {
std::cout << e.what() << "n";
}

return 0;
}

我希望输出是"我的错误:我的错误:错误消息",但相反,它是一个简短的随机字符序列,大概直到命中

如果我没有在myError::what()中添加消息(即注释掉的行(,那么输出只是"错误消息",因此一切都按预期工作。 为什么会这样?

我在Windows上运行gcc 8.1.0,安装选项是x86_64-posix-she-rev0。

而且我有点意识到nested_exception,并且我正在丢失有关跟踪等的一些信息。

编辑:作为一种解决方法,在构造函数中添加消息"我的错误"会产生预期的输出:

explicit myError( const std::string& error ) :
m_error { "My error: " + error }
{}
explicit myError( const char* error ) :
m_error { "My error: " + std::string{ error } }
{}
const char* what() const noexcept override
{
return m_error.c_str();
}

所以return ("My error: " + m_error).c_str();似乎有些问题.

在:

return ("My error: " + m_error).c_str();

c_str()返回指向由串联创建的临时字符串的内部缓冲区的指针。此字符串的生存期在return语句之后立即结束,使返回的指针悬空且其使用未定义。