2013-07-03 162 views
4

我不確定我的自定義異常方法是否正確。我想要做的是自定義消息拋出異常,但似乎我創建了一個內存泄漏...帶消息的C++異常

class LoadException: public std::exception { 
private: 
    const char* message; 
public: 
    LoadException(const std::string message); 
    virtual const char* what() const throw(); 
}; 


LoadException::LoadException(const std::string message) { 
    char* characters = new char[message.size() + 1]; 
    std::copy(message.begin(), message.end(), characters); 
    characters[message.size()] = '\0'; 
    this->message = characters; 
} 

我用它如下:

void array_type_guard(Local<Value> obj, const std::string path) { 
    if (!obj->IsArray()) { 
     throw LoadException(path + " is not an array"); 
    } 
} 

try { 
    objects = load_objects(); 
} catch (std::exception& e) { 
    ThrowException(Exception::TypeError(String::New(e.what()))); 
    return scope.Close(Undefined()); 
} 

我怕陣列創建在構造函數中永遠不會被刪除。但我不知道如何刪除它 - 我應該添加析構函數還是使用完全不同的方法?

更新

我其實是試圖用串類,如下所示:

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

LoadException::LoadException(const std::string message) { 
    msg = message.c_str(); 
} 

const char* LoadException::what() const throw() { 
    return msg; 
} 

但無法獲得錯誤信息,那麼 - 當我打印的「顯示一些隨機輸出什麼()」。

+2

只需使用'string'來存儲消息。或者是否有'char *'的原因? –

+0

不,沒有char *的理由。我將代碼更改爲字符串。謝謝。 –

+0

或者只是用一個析構函數來刪除分配的字符數組。 –

回答

11

你可以採取的std:string

class LoadException: public std::exception { 
private: 
    std::string message_; 
public: 
    explicit LoadException(const std::string& message); 
    virtual const char* what() const throw() { 
     return message_.c_str(); 
    } 
}; 


LoadException::LoadException(const std::string& message) : message_(message) { 

} 

優勢,那麼C++作用域會照顧清理東西你

+1

會更好地傳遞非const值並移動構造'message_' –

+0

謝謝。它以這種方式工作,但我不知道爲什麼......它看起來像字符串被複制到異常對象。我對嗎? –

+0

它工作是因爲'string'自己分配和釋放緩衝區。它和你做的完全一樣,但是另外它在析構函數中刪除了分配的內存。 –

12

我如何
throw std::runtime_error("My very own message");

0

在構造函數中有

Printer::Printer(boost::asio::io_service& io, unsigned int interval) { 
    if (interval < 1) { 
     throw std::runtime_error("Interval can't be less than one second"); 
    } 
} 

當創建對象時

try { 
    Printer p{io, 0}; 
} catch (std::exception& e) { 
    std::cerr << e.what() << std::endl; 
} 

該程序將退出並顯示消息。