c++ - 在双向链表的析构函数中为 RtlvalidateHeap 指定的地址无效
问题描述
运行程序时,我不断收到此错误。
HEAP[PA1.exe]: Invalid address specified to RtlValidateHeap( 00C40000, 00C48880 )
PA1.exe has triggered a breakpoint.
我将它缩小到我的析构函数,但我不确定它为什么会导致它。
List::~List()
{
if (!nullptr) {
Item* toDelete = Head;
while (toDelete != NULL) {
Item* next = toDelete->Next;
delete toDelete;
toDelete = next;
}
}
编辑:我看到我的问题出在我的构造函数中,但是我不确定我需要改变什么。当我开始进行深层复制时,就会发生错误。所以我的猜测是它的复制构造函数。
List::List()
{
Head = 0;
Prev = 0;
Next = 0;
}
List::~List()
{
Item* move = Head;
while (Head)
{
Head = move->Next;
delete move;
move = Head;
}
}
List::List(const List& copy)
{
Head = copy.Head;
Next= copy.Next;
Prev= copy.Prev;
}
List& List::operator=(const List& t)
{
Head = t.Head;
Prev = t.Prev;
Next = t.Next;
return *this;
}
解决方案
虽然您的代码不足以确定结论,但查看症状和析构函数,您很可能没有遵守3 的规则。
规则 3 告诉你,如果你需要一个特定的析构函数,例如因为你有一个指针,你至少需要实现复制构造函数和复制赋值。
为什么 ?
- 您的班级中有一个指针
Next
。 - 不知何故,您分配了一些内存并将地址放入该指针中(因为如果您不这样做,您就不会在最后删除指向的对象
- 如果您没有复制构造和复制分配,那么当您 cpy 一个 List 元素时,您将照原样复制它的指针。第一个要删除的对象(例如临时对象?)将删除指针。当第二个对象被销毁时,它的析构函数将删除一个已经被删除的指针。
现在,如果您不喜欢注意 3 的规则,有一个更好的选择:避免使用原始指针。尝试shared_ptr
改用。这些指针自己管理内存(例如,当不再使用对象时将其删除)。包括在复制和删除副本的情况下。
推荐阅读
- python - 比术语聚合更有效的聚合?
- amazon-web-services - 跟踪 AWS 对象/服务
- vba - VBA:如何以不同方式格式化文本框文本的不同部分?
- c# - 无法停止异步 TCP 服务器 Windows 服务
- javascript - 我可以只更新 Bootstrap JS 文件吗?
- c# - FlowDocument占用一半空间?
- android - LIBgdx,通过在渲染方法中使用 rectangle.overlaps(rectangle) 方法检测之间的碰撞会给出 StackOverFlow 错误
- python-3.x - 在 Python 3 中制作简单的异步套接字聊天服务器的明显方法是什么?
- sql-server - SQL Server:计算
- javascript - 我想用 javascript 分割窗口 url