最近遇到一个问题,产生了coredump, 用gdb看也没看出真正原因,合作方同事提醒才看出来。
模拟了一下出错场景,代码如下:
class Person{ private: int *m_data; static Person *pInstance; public: Person(){ printf("Person\n"); m_data = new int[60]; printf("Person done\n"); } ~Person(){ printf("~Person\n"); if(m_data){ delete m_data; m_data = NULL; } printf("~Person done\n"); } static Person* getInstance(){ if(NULL == pInstance){ pInstance = new Person(); } return pInstance; } static void destroyInstance(){ if(pInstance){ delete pInstance; pInstance = NULL; } } } Person* Person::pInstance = NULL; class Person *gpPersonInstance = NULL; void init(){ gpPersonInstance = Person::getInstance(); } void finilize(){ if(gpPersonInstance){ delete gpPersonInstance; gpPersonInstance = NULL; } //Person::destroyInstance(); } int main(void){ init(); printf("gpPersonInstance addr: %p\n", gpPersonInstance); finilize(); printf("pInstance addr: %p\n", Person::getInstance()); init(); finilize(); }
在第一次init() finilize(); 正常,把单例实例销毁了,全局制作也gpPersonInstance = NULL; 但pInstance 没有设置为NULL。
当第二次init()时,由于pInstance不为NULL,所以直接把之前的值赋值给gpPersonInstance 了, 再次finilize() 就会delete一个不是自己new的对象的地址,产生coredump。
在finilize()函数中把
if(gpPersonInstance){ delete gpPersonInstance; gpPersonInstance = NULL; }
用
Person::destroyInstance(); 代替就没有问题