2013-07-03 130 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; 
} 

该程序将退出并显示消息。