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;
}

我已经阅读了其他涉及调试断言失败的问题,但有些事情告诉我调试断言失败可能以各种方式发生。结果,我几乎不知道为什么会为我的代码显示错误消息......我的析构函数是否有问题,正如我目前所怀疑的那样?非常感谢您提前提供的帮助!

4

2 回答 2

2

问题是因为您显式调用析构函数:

u1.Update::~Update();

这样它被调用两次导致未定义的行为,我想 delete [] date; 被调用两次,第二次在已经释放的内存上。

您的代码中的另一个问题是您正在为数组使用裸指针:

int * date;

这实际上是 C++ 中相当低级的编程风格,可能会导致很多问题。您应该实现类复制构造函数和赋值运算符 (*),它们将在复制更新类时分配新的日期数组,否则您将再次遇到多个日期指针删除的问题。

最好的方法是使用矢量

std::vector<int> date;

(*)我认为很好的链接解释了适用于此处的三规则(或自 C++11 规则五):三规则成为 C++ 11 的五规则?

于 2013-05-05T19:38:40.523 回答
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您可以使用int date[3].

于 2013-05-05T19:28:50.177 回答