我最近在做一些套接字編程,並開始用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()
方法現在是不完整的,因爲我想通過顯示錯誤代碼的文本含義,但我還沒有寫過。
我在Visual Studio中試過這段代碼,但沒有像我期望的那樣工作,所以what()
方法返回垃圾。花了相當一段時間試圖找出問題並嘗試不同的事情後,我最終嘗試了一種不同的編譯器。
使用MinGW(GCC)代碼編譯和按預期運行,消息顯示爲我認爲他們會(如果任何人有興趣,我只是試圖執行connect()
時,未連接到Internet)。
我剛剛學習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();
}
要調用UB時,*流*對象將在方法返回一個這樣的char *通過c_str返回(破壞)是一個懸擺指針。你需要在類中使用char []來保持指針有效。 – 2013-02-10 21:41:22
感謝您的評論,我認爲這是它,但在堆中分配的流產生了相同的結果。難道是'str()'調用會創建一個在某個時刻被銷燬的臨時對象? – 2013-02-10 21:57:40
關於編輯,是的,'stringstream :: str()'返回一個底層字符串的副本,這是這個上下文中的臨時字符串。 – juanchopanza 2013-02-10 22:02:40