C++新手:析构函数
我只是创建一个简单的列表,然后销毁它。出了问题,我总是收到这个恼人的错误消息:
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
这是代码:
#include<iostream>
#include<Windows.h>
using namespace std;
struct node
{
int data;
node *next;
};
class list
{
protected:
node *top;
public:
list()
{
top=NULL;
}
list random()
{
int x=rand()%10;
for(int i=0; i<x; i++)
{
node *p=new node;
p->data=rand()%100;
p->next=top;
top=p;
}
return *this;
}
void show()
{
for(node *p=top; p; p=p->next)
{
cout<<p->data<<" ";
}
cout<<"\n";
}
~list()
{
node *r;
for(node *p=top; p; p=r)
{
r=p->next;
delete p;
}
}
};
int main()
{
srand(GetTickCount());
list a;
a.random().show();
return 0;
}
I'm just creating a simple list and then destroying it. And something is going wrong and I always get this annoying error message:
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Here's the code:
#include<iostream>
#include<Windows.h>
using namespace std;
struct node
{
int data;
node *next;
};
class list
{
protected:
node *top;
public:
list()
{
top=NULL;
}
list random()
{
int x=rand()%10;
for(int i=0; i<x; i++)
{
node *p=new node;
p->data=rand()%100;
p->next=top;
top=p;
}
return *this;
}
void show()
{
for(node *p=top; p; p=p->next)
{
cout<<p->data<<" ";
}
cout<<"\n";
}
~list()
{
node *r;
for(node *p=top; p; p=r)
{
r=p->next;
delete p;
}
}
};
int main()
{
srand(GetTickCount());
list a;
a.random().show();
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这:
应该是:
原因是您的版本返回实例
a
的副本,并且该副本在调用show()
后被破坏..并且破坏会破坏与a
使用的内存相同。如果您确实想让random()
返回一个副本,则需要实现一个复制构造函数,该构造函数对a
具有的内部列表进行深层复制。This:
should be:
The reason is that your version returns a copy of your instance
a
, and that copy get destructed aftershow()
is called.. and that destruction destroys the same memory as thata
is using. If you really want to haverandom()
return a copy, you need to implement a copy constructor that does a deep copy of the internal list thata
has.您的问题是您正在复制
list
但没有定义复制构造函数。隐式定义的复制构造函数只会复制top
指针,因此您最终会尝试删除同一节点链两次。当您从按值返回
*this
副本的random()
成员函数返回 *this;
时,就会发生复制。最短的修复方法是通过在类的私有部分声明复制构造函数和复制赋值运算符来使您的类不可复制。
然后你可以让
random
返回void
,似乎没有一个很好的理由为什么它也制作一个副本。然后,您可以这样调用它:
较长的解决方法是通过完整实现
list(const list&)
和list& 来使您的
正确复制正在复制的源list
可复制; operator=(const list&)list
的所有节点。Your problem is that you are copying your
list
but you don't define a copy constructor. The implicitly defined copy constructor will just copy thetop
pointer so you end up attempting to delete the same chain of nodes twice.The copy occurs when you
return *this;
from yourrandom()
member function returning a copy of*this
by value.The shortest fix would be to make your class non-copyable by declaring a copy constructor and copy assignment operator in the private section of your class.
You can then make
random
returnvoid
, there doesn't seem to be a good reason why it makes a copy as well.You could then just call it like this:
The longer fix would be to make your
list
copyable by making a full implementation oflist(const list&)
andlist& operator=(const list&)
that correctly duplicates all the nodes of the sourcelist
being copied.这不是一个“烦人的错误消息”,它告诉您您的程序以某种方式损坏了内存。实际上相当重要。
当您
返回 *this
时,您创建了列表的副本,但您从未定义复制构造函数,因此最终会两次删除顶部节点。It's not an "annoying error message", it is telling you that your program has somehow corrupted memory. Quite important actually.
You create a copy of your list when you
return *this
, but you never define a copy constructor, so you end up deleting your top node twice.