调用析构函数时出错
Error when calling destructor
嗨,我正在学习运算符重载..我注意到程序在调用析构函数时崩溃.. 任何帮助不胜感激。谢谢
#include<iostream>
using namespace std;
class Overload
{
private:
int a, *b;
public:
Overload():a(0) {cout << "defaultn"; };
Overload(int x);
Overload operator+(Overload & rhs);
int geta();
int* getb();
void setb();
void PrintVals(const Overload & val);
~Overload();
};
Overload::Overload( int x)
{
cout << "Parameterized constructorn";
a = x;
b = new int[a];
}
int Overload::geta()
{
return a;
}
int* Overload::getb()
{
return b;
}
void Overload::setb()
{
int val;
cout << "setting b valuesn";
for (int i = 0 ; i <= a; i++)
{
cin >> val;
b[i] = val;
}
}
Overload Overload::operator+(Overload & rhs)
{
Overload temp;
temp.a = this->a + rhs.a;
temp.b = new int[temp.a];
*temp.b = *(this->b) + *(rhs.b);
cout << "inside overload + vale of LHS:" << *(this->b) << endl;
cout << "inside overload + vale of RHS:" << *(rhs.b) << endl;
cout << "inside overload + vale of temp:" << *temp.b << endl;
cout << "Address of b(temp):" << temp.b << endl;
temp.b++;
this->b++;
rhs.b++;
*temp.b = *(this->b) + *(rhs.b);
cout << "inside overload + vale of LHS:" << *(this->b) << endl;
cout << "inside overload + vale of RHS:" << *(rhs.b) << endl;
cout << "inside overload + vale of temp:" << *temp.b << endl;
cout << "Address of b(temp):" << temp.b << endl;
return temp;
}
Overload::~Overload()
{
cout << "Destructor n";
cout << "Address deallocated b:" << b;
delete [] b;
}
void Overload::PrintVals(const Overload & val)
{
int val1, *val2;
val1 = this->a;
val2 = this->b;
cout << "Printing values: a: " << val1 << " b:" << *val2;
}
int main()
{
Overload X(1),Y(1),Z;
int val1, *val, val2, val3;
//Z = X + Y;
val1 = Y.geta();
val2 = X.geta();
Y.setb();
val = Y.getb();
printf("val of y b: %dn",*val);
printf("val of x a: %dn",val1);
X.setb();
val = X.getb();
printf("val of x b: %dn",*val);
printf("val of x a: %dn",val2);
Z = X + Y;
val = Z.getb();
val3 = Z.geta();
val--;
for( int i = 0; i < val3; i++)
{
printf("address of (b) Z: %p n",val);
printf("val of z b: %dn",*val);
printf("val of z a: %dn",val3);
val++;
}
}
输出:。。。破坏者第 1 部分(4815,0x7fff73def300( malloc:* 对象 0x100200004 的错误:未分配正在释放的指针* 在malloc_error_break中设置断点进行调试地址已解除分配 b:0x100200004(lldb(
您还应该实现复制构造函数和赋值运算符。
默认构造函数未初始化b
。换句话说,代码不会构造处于有效状态的对象。 当析构函数调用时b
可能是任何东西delete[] b
这会导致错误 - 你还期待什么?
一个相关的问题是默认构造的复制构造函数和复制赋值运算符将简单地复制b
。因此,如果从中复制的对象被销毁,则复制到的对象将留下一个悬空指针,这在其销毁时会导致错误。
主要的教训是:如果你不知道自己在做什么(而且你不知道(,就不要使用原始指针。而是使用std::vector
或std::unique_ptr
或标准提供的其他方法,这些方法将为您处理此类事情。
有两个令人讨厌的错误会导致您的错误:
1.缓冲区溢出:
第一个致命错误是缓冲区溢出 setb()
: b
指向一个a
元素数组,因此您无法在不损坏内存的情况下设置 b[a]:
for (int i = 0; i < a; i++) // strictly < a, not <=a !!
2.原始指针的默认副本:
第二个致命错误是在operator+ ()
的实现中。 问题是返回temp
的副本(调用表达式中匿名临时对象的复制构造(,然后分配给 Z(赋值运算符(:
Overload temp; // you create a logcal temporary object
...
temp.b = new int[temp.a]; // you allocate the array
...
return b; // you return a COPY of the temp object
} // here the local temp object gets destroyed
但是,由于您既没有定义复制构造函数,也没有定义赋值运算符,因此使用默认运算符。 它们构成了对象的成员副本,即指针只是按原样复制。 结果是Z.b
将包含指针temp.b
的副本,但temp.b
已经在运算符+((的末尾删除了!因此 Z 将引用一个悬空的指针,造成很大的伤害,尤其是在离开 main(( 时,Z 的析构函数将尝试 d 第二次删除它!
创建一个复制构造函数和一个赋值运算符,用于正确分配新的b
指针。这将解决第二个问题。
并且,请不要像(this->b++
那样增加操作数的指针:它会永久更改 b poitner,并且当操作数超出范围时,删除不会识别它。
顺便说一下,即使它不是问题的直接原因,您也可以通过添加两个操作数的大小来启动temp
大小a
,但您仅为第一个操作数的大小分配b
。
3. 其他备注:
默认构造函数不会将b
初始化为显式nullptr
。 这样做是一种安全的做法,但这不是您在这里遇到的问题的直接原因。
在 operator+(( 中,最好在不访问其内部的情况下初始化 temp:Overload temp (a);
将更易于维护且不易出错。
我不知道这是否是你的意图,但只添加了 b 指向的数组的第一个值: *temp.b = *(this->b) + *(rhs.b);
与您使用的最大大小为 1 main()
一样,这里不是问题。 但对于将来,最好使用循环来复制所有元素。
最后一句话:你有没有想过你的类的用户可以做一些奇怪的事情,比如:你的运算符+Overload E, G(0), H(1); E = H+G;
然后尝试访问空指针?
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 调用析构函数时出错
- Dev-C++和Code::Blocks中的析构函数出错
- 在 VC 6.0 中使用函数指针调用虚拟析构函数时出错
- 调用析构函数时出错
- 这个C++容器的析构函数哪里出错了
- 析构函数删除数组时出错
- 为什么我的输出流seg出错,而我的虚拟析构函数不起作用,但当我杀死虚拟的时候,它起作用了
- DAG析构函数出错