Unhandled exception when application is finishing
I have a singleton (I know that is a bad pattern). To control the cleaning process, I'm using a shared pointer. The relevant code is:
#ifndef _GLOBAL_LOG_H_
#define _GLOBAL_LOG_H_
namespace glog{
class CGlobalLog;
typedef boost::shared_ptr<CGlobalLog> globalLogPtr;
class CGlobalLog
{
private:
static globalLogPtr m_instance;
LogLevel minimiumLogLevel;
CGlobalLog(void);
static void deleter(CGlobalLog *ptr){
try{
delete ptr;
}
catch(std:: e)
{
std::cout << e.what() << "\n";
}
}
static void create() { m_instance.reset( new CGlobalLog, &CGlobalLog::deleter ); }
void addMessage_(const std::string& appender, LogLevel level /*= LOGLEVEL_INFO*/,const char* msg, va_list args );
~CGlobalLog(void);
public:
static globalLogPtr& getInstance();
void addMessage(const std::string& message, std::string appender, LogLevel level = LOGLEVEL_INFO);
};
开发者_Go百科globalLogPtr CGlobalLog::m_instance;
};
#endif // _GLOBAL_LOG_H_
The program works fine, but when program finish, an unhandled exception is thrown in this point:
static void deleter(CGlobalLog *ptr){
try{
delete ptr; //<-- Unhandled exception
}
catch(std:: e)
{
std::cout << e.what() << "\n";
}
}
The catch doesn't catch the exception so I don't know what to do to profile my error. The exact code where error is throw is a boost library file checked_delete.hpp, here:
// verify that types are complete for increased safety
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
How do I need to locate this error? Some ideas?
Thanks!!!
I generally don't expect to see a shared pointer on a singleton. Just returning a reference to your singleton and never keeping a reference to it laying around is a good practice.
struct Foo {
static Foo &instance() {
static Foo foo;
return foo;
}
};
struct Bar {
void someMethod() {
Foo &foo = Foo::instance(); // just grab a reference every time you need it
// ...
}
};
If you wish to keep the shared pointer and need to clean up resources in manual way, create a tear down method. The boost::shared_ptr
will clean up the memory eventually.
Personally, I think using a shared pointer externally is inferior. I wrote some code to demonstrate a tear down and it didn't seem generally applicable without knowing why you need one.
If you want an explicit delete, then write one.
struct Foo {
static Foo *foo = 0;
static Foo &instance() {
if (!foo)
throw std::logic_error("Already deleted");
return *foo;
}
static void Init() {
if (foo)
throw std::logic_error("Already created");
foo = new Foo;
}
static void Destroy() {
if (!foo)
throw std::logic_error("Already deleted");
delete foo;
foo = 0;
}
};
In the case of logging, the logic errors should be superfluous. If logging isn't valid when you ask for it, then it is unlikely that your application is in a valid state.
精彩评论