自定义异常显示可变消息,不同编译器中的行为不同

时间:2013-02-10 21:36:45

标签: c++ windows exception winsock2

我最近正在做一些套接字编程并开始用C ++编写代码。由于我正在尝试编写的程序将有几个必须通过套接字进行通信的组件,所以我决定在一个类中包装套接字通信。

由于可能发生多个错误,我决定为套接字异常创建一个类,我这样定义:

class SocketException: public std::exception {
public:
  SocketException(const std::string &message);
  ~SocketException() throw();
  virtual const char * what() const throw();
private:
  std::string msg;
};

实施如下:

SocketException::SocketException(const std::string &message) : msg(message) {}
SocketException::~SocketException() throw() {}

const char * SocketException::what() const throw() {
  std::stringstream stream;
  stream << msg + " Error number: ";
  stream << WSAGetLastError();
  return stream.str().c_str();
}

截至目前,what()方法的实现尚未完成,因为我想通过FormatMessage()显示错误代码的文本含义,但我还没有写过。

我在Visual Studio中尝试此代码,但不是像我预期的那样工作what()方法返回垃圾。在花了很长时间试图找出问题并尝试不同的事情后,我最终尝试了不同的编译器。

使用MinGW(GCC)代码编译并按预期运行,消息显示为我认为的消息(如果有人感兴趣我只是在没有连接到Internet时尝试执行connect() )。

我只是在学习C ++,我想知道问题出在哪里或者做什么是合适的方式。

编辑:感谢您的评论和回答,起初我认为是这样的,所以我使用new来分配流(即使知道它是一个泄漏,只是为了我理解的尝试new使用堆),结果是一样的,这就是我所拥有的:

const char * SocketException::what() const throw() {
  std::stringstream *stream = new std::stringstream();
  *stream << msg + " Error: ";
  *stream << WSAGetLastError();
  return (*stream).str().c_str();
}

2 个答案:

答案 0 :(得分:1)

您正在返回指向what函数本地变量的指针,从而使调用者留下悬空指针:

const char * SocketException::what() const throw() {
  std::stringstream stream;  // this stringstream will die on exiting this scope
  stream << msg + " Error number: ";
  stream << WSAGetLastError();
  return stream.str().c_str();
}

这是未定义的行为。这意味着任何事情都可能发生。

安全返回const char*的方法示例就是这样(显然它没有原始的预期功能,仅用于说明目的):

const char * SocketException::what() const throw()
{
  return msg.c_str(); // msg lives as long as this SocketException instance 
}

这已定义了行为,前提是SocketException对象死后指针未被解除引用。

答案 1 :(得分:0)

怎么样 throw std::runtime_error("My very own message");