1. 程式人生 > >全域性變數誤用導致單例模式中的多次銷燬例項產生coredump

全域性變數誤用導致單例模式中的多次銷燬例項產生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();  代替就沒有問題