2013-05-05 128 views
0

出於某種原因,當我使用的析構函數我更新類,調試斷言失敗消息顯示...調試斷言失敗的消息

這裏是我的更新類略去了一些代碼。放置在頭文件中:

using namespace std; 

class Update 
{ 
private: 
    int day, month, year; 
static const int FIELD_SIZE = 3, DEFAULT_DAY = 12, DEFAULT_MONTH = 12, 
    DEFAULT_YEAR = 1999, DAYS_IN_MONTH = 30, MONTHS_IN_YEAR = 12, DAYS_IN_YEAR = 365; 

int * date; 

public: 
static int dateUpdate; 

Update(int D, int M, int Y) 
{ 
    day = D; 
    if (day < 1 || day > DAYS_IN_MONTH) 
     day = DEFAULT_DAY; 
    month = M; 
    if (month < 1 || month > MONTHS_IN_YEAR) 
     month = DEFAULT_MONTH; 
    year = Y; 
    if (year < 1) 
     year = DEFAULT_YEAR; 

    date = new int [FIELD_SIZE]; 
    date[0] = day, date[1] = month, date[2] = year; 

    dateUpdate++; 
} 

~Update() 
{ 
    delete [] date; 

    dateUpdate--; 
} 

};

,這裏是一個CPP文件我的測試類:

#include <iostream> 
#include "Update.h" 

int Update::dateUpdate = 0; 

int main() 
{ 
Update u1(29, 12, 2000); 
u1.Update::~Update(); 

return 0; 
} 

我已經通過涉及調試斷言失敗等問題,讀,但東西告訴我一個調試斷言失敗以不同的方式,可能會發生。結果,我很少知道爲什麼錯誤信息顯示在我的代碼中......現在我懷疑我的析構函數有什麼問題嗎?非常感謝你的幫助!

+3

爲什麼你明確地調用析構函數? – olevegard 2013-05-05 19:24:40

+0

爲什麼你使用'new []'和'delete []'而不是一個容器爲你做了繁重的工作(你已經做了錯誤的例子)? – chris 2013-05-05 19:25:44

+0

難道不是這樣做的嗎?我當時正在看msdn.microsoft.com/en-us/library/35xa3368%28v=vs.80%29.aspx ... – user1800967 2013-05-05 19:25:59

回答

1

您應該更改此行:
date [0] = day,date [1] = month,date [2] = year;

要:

date[0] = day; 
date[1] = month; 
date[2] = year; 

您正在使用逗號操作,它返回最後一個表達式的結果。這與逗號在初始化中的操作方式不同。

此外,在您的main函數中,您不需要顯式調用析構函數。

你的約會方法不能處理的1月31日,也沒有12月31日

您可以訪問函數的參數,而不是直接在功能上進行復印。例如:day = D;是不需要的;直接訪問參數:if ((D < 1) ...

如果使用無符號整數,則不需要檢查負數。我從未經歷過我的生活中的一天,一年或一年。

由於這是C++而不是Java或C#,因此不需要動態分配變量。因此,您可以使用int date[3]而不是使用int * date

+0

使用逗號仍然有效(它會將每個值賦給每個變量),但絕對不是好習慣。 – chris 2013-05-05 19:30:28

+0

對於我正在進行的具體任務,負數很好。所以很酷。謝謝。 – user1800967 2013-05-05 19:47:23

2

的問題是,因爲你是顯式調用析構函數:

u1.Update::~Update(); 

這種方式被稱爲兩次導致未定義的行爲,我想刪除[]日期;被稱爲兩次,第二次在alreade釋放記憶。

在你的代碼的另一個問題是,你正在使用裸指針數組你:

int * date; 

這其實是在C語言相當低級別的編程風格++,並可能導致很多問題。您應該實現類複製構造函數和賦值運算符(*),它將在您的Update類將被複制時分配新的日期數組,否則您將再次遇到多個日期指針刪除的問題。

的最好方法是使用像

std::vector<int> date; 

(*)載體,我認爲很好的鏈接,其中的規則,三個(或因爲C++ 11的5種規則)此處適用解釋:Rule-of-Three becomes Rule-of-Five with C++11?

+0

這就是手動內存管理如此糟糕的原因。你忽略提到需要一個賦值運算符,並且在C++ 11中需要移動這些運算符的版本。此外,對對象調用析構函數兩次本身也是未定義行爲,即使它是空的。 – chris 2013-05-05 19:42:07