I’m doing some socket programming lately and starting to code in C++. As the program I’m trying to write will have several components that have to communicate via sockets I decided to wrap up socket communication in a class.
Since there are several errors that can happen I decided to create a class for socket exceptions, I defined it like this:
class SocketException: public std::exception {
public:
SocketException(const std::string &message);
~SocketException() throw();
virtual const char * what() const throw();
private:
std::string msg;
};
The implementation is as follows:
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();
}
The implementation of the what() method is incomplete as of now, because I’d like to show the text meaning of the error code via FormatMessage() but I haven’t written that yet.
I was trying this code in Visual Studio but instead of working as I expected the what() method returns garbage. After spending quite some time trying to figure out the problem and trying different things I ended up trying a different compiler.
Using MinGW (GCC) the code compiles and runs as expected, messages are shown as I thought they’d be (if anyone is interested I’m just trying to perform a connect() when not connected to the Internet).
I’m just learning C++, I’d like to know where the problem is or what would be the appropriate way of doing it.
EDIT: Thanks for the comment and answer, at first I thought that’d be the case so I used new to allocate the stream (even knowing it’d be a leak, just to try as I understand new uses the heap) and the result was the same, this is what I had:
const char * SocketException::what() const throw() {
std::stringstream *stream = new std::stringstream();
*stream << msg + " Error: ";
*stream << WSAGetLastError();
return (*stream).str().c_str();
}
You are returning a pointer to a variable that is local to your
whatfunction, thus leaving the caller with a dangling pointer:That is undefined behaviour. It means anything could happen.
An example of a method safely returning
const char*would be this (obviously it doesn’t have the intended functionality of the original, it is just for illustration purposes):This has defined behaviour provided the pointer is not dereferenced after the
SocketExceptionobject dies.