为什么析构函数在被调用时会产生错误?
Why does destructor create a bug when it's being called?
我创建了一个日历类,其中一切似乎都运行良好,但是就在程序结束之前,当调用析构函数时,它会导致调试断言失败!
这是类:
//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;
}
可能是什么问题?我不是为类的变量创建内存吗?
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) {}
};
现在,默认的复制构造函数、赋值运算符和析构函数将为您工作,并且没有要处理的指针。
让我们看一下你的复制构造函数:
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;
但我真的认为这里根本不需要指针,这意味着你不需要分配内存,你不需要担心复制,你不必担心内存泄漏的杂散指针。事实上,如果你没有指针,你甚至不需要复制构造函数、赋值运算符或析构函数。我建议您阅读有关零规则的信息。
不,您没有正确构造数据。
day = pday;
month = pmonth;
year = pyear;
是一个指针赋值,从参数复制地址,而不是它们的值。
正确的方法是(假设我们要复制 1 个元素(:
*day = *pday;
*month = *pmonth;
*year = *pyear;
您还将数组删除delete[]
与单元素new
混合在一起(不带[]
(。这是未定义的行为。
另一件事是,day = new int(sizeof(pday));
创建一个int
,该使用指针大小的值进行初始化。这似乎很奇怪。
- 不命名构造函数和析构函数上的类型错误
- 导致 Seg 错误的 SingleLinkedList 的析构函数
- LINUX 操作系统上的错误:令牌之前预期的构造函数、析构函数或类型转换'('?
- 矢量擦除调用的错误析构函数
- 在析构函数中调用"delete"运算符时"compiler is out of heap space"编译器错误
- 在Visual Studio中,与std::async一起使用时不调用"thread_local"变量"析构函数,这是一个错误吗?
- 导致堆缓冲区错误的动态分配数组的析构函数
- 非默认析构函数会导致不完整的类型错误
- 析构函数删除错误的元素
- 使用自定义工具集获取动态退出析构函数链接错误 - eh 矢量析构函数
- 使用 boost::thread 运行函子,但析构函数被错误地调用
- 错误 c++ 在令牌之前'('预期的构造函数、析构函数或类型转换
- 错误:在“(”标记之前进行预期的构造函数、析构函数或类型转换.即使我有一个构造函数
- 模板类中的析构函数给出错误
- 在析构函数内取消引用指针时出现分段错误
- 模板化子类析构函数中的隔离错误
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 获取错误:在“(”标记之前进行预期的构造函数、析构函数或类型转换
- 显式调用类的析构函数时出现错误
- C++析构函数调用了错误的对象