2015-11-03 77 views
-3

我已經創建了一個Calendar類,其中一切似乎都正常工作,但在程序結束之前,調用析構函數時會導致調試斷言失敗!爲什麼析構函數在被調用時會創建一個bug?

這是類:

//constructor 
Calendar::Calendar(const int *pday, const int *pmonth, const int *pyear){ 
    day = new int(sizeof(pday)); 
    month = new int(sizeof(pmonth)); 
    year = new int(sizeof(pyear)); 

    day = pday; 
    month = pmonth; 
    year = pyear; 
} 

//copy constructor 
Calendar::Calendar(const Calendar &rhs){ 
    day = new int(sizeof(rhs.day)); 
    month = new int(sizeof(rhs.month)); 
    year = new int(sizeof(rhs.year)); 

    day = rhs.day; 
    month = rhs.month; 
    year = rhs.year; 
} 

//operator '=' overload 
Calendar& Calendar::operator=(const Calendar &rhs){ 
    delete[] day; 
    delete[] month; 
    delete[] year; 

    day = new int(sizeof(rhs.day)); 
    month = new int(sizeof(rhs.month)); 
    year = new int(sizeof(rhs.year)); 

    day = rhs.day; 
    month = rhs.month; 
    year = rhs.year; 

    return *this; 
} 

//deconstructor 
Calendar::~Calendar(){ 
    delete[] day; 
    delete[] month; 
    delete[] year; 
} 

可能是什麼問題呢?我是不是爲類的變量創建內存?

+0

你爲什麼使用'delete []'?爲什麼你使用指針而不是整數? – BlackDwarf

+0

new [size]也許?不是新的()或簡單地刪除 – Pumkko

+1

爲什麼4/4/4或8/8/8是您的默認日期? – molbdnilo

回答

1

讓我們看看你的拷貝構造函數:

Calendar::Calendar(const Calendar &rhs){ 
    day = new int(sizeof(rhs.day)); 
    month = new int(sizeof(rhs.month)); 
    year = new int(sizeof(rhs.year)); 

    day = rhs.day; 
    month = rhs.month; 
    year = rhs.year; 
} 

首先,你分配內存並將其分配給您的會員。然後用rhs對象的指針覆蓋這個對象中的指針,導致你有兩個對象指向同一個內存。當一個對象被破壞的其他對象將有野指針,試圖刪除它們會導致未定義行爲

一種解決方案是使用反引用的值複製,例如

*day = *rhs.day; 

但我真的認爲沒有必要在指針都在這裏,這意味着你不需要分配內存,您不必擔心複製,你不必擔心野指針的內存泄漏。事實上,如果你沒有指針,你甚至不需要複製構造函數,賦值運算符或析構函數。我建議你閱讀約the rule of zero

4

當您使用new創建指針時,請使用delete將其刪除。當您使用new[]創建指針時,請使用delete[]將其刪除。混合它們是未定義的行爲,這就是你正在做的。您創建new的指針,但你delete[]

刪除它,我相信你的意思是創建你爲什麼要使用指針喜歡這裏

day = new int; 
month = new int; 
year = new int; 

指針?使用指針似乎不是在這裏做的。一個簡單的Calendar類存儲的日,月,年可實現爲

Calendar 
{ 
private: 
    int day_; 
    int month_; 
    int year_; 
public: 
    Calendar(int day = 0, int month = 0, int year = 0) : day_(day), month_(month), year_(year) {} 
}; 

現在默認的拷貝構造函數,賦值操作符和析構函數會爲你工作,並沒有指針來處理。

1

不,你沒有正確構建數據。

day = pday; 
month = pmonth; 
year = pyear; 

是一個指針分配,從參數中複製地址,而不是它們的值。

正確的方法是(假設我們要複製1元):

*day = *pday; 
*month = *pmonth; 
*year = *pyear; 

您還混合陣列與單個元素new刪除delete[](不[])。這是未定義的行爲。

另一件事,day = new int(sizeof(pday));創建一個int用一個指針大小的值初始化。這似乎很奇怪。

相關問題