全局变量误用导致单例模式中的多次销毁实例产生coredump

最近遇到一个问题,产生了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();  代替就没有问题

猜你喜欢

转载自blog.csdn.net/liubangbo/article/details/84846392