【问题标题】:Invalid Adress Specified to RtlvalidateHeap in Destructor for doubly linked list在双向链表的析构函数中为 RtlvalidateHeap 指定的地址无效
【发布时间】:2020-05-04 20:30:12
【问题描述】:

我在运行程序时不断收到此错误。

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

【问题讨论】:

  • 当您意识到程序崩溃的位置通常与错误所在的位置无关时,编程会变得更容易理解。缩小坠机地点的范围很重要,但它通常只是谜团的第一条线索。

标签: c++ visual-c++ linked-list destructor doubly-linked-list


【解决方案1】:

虽然您的代码不足以确定结论,但查看症状和析构函数,您很可能不尊重rule of 3

规则 3 告诉你,如果你需要一个特定的析构函数,例如因为你有一个指针,你至少需要实现拷贝构造函数和拷贝赋值。

为什么?

  • 您的班级中有一个指针Next
  • 您以某种方式分配了一些内存并将地址放入该指针中(因为如果您不这样做,您就不会在末尾删除指向的对象
  • 如果您没有复制构造和复制赋值,那么当您 cpy 一个 List 元素时,您将照原样复制它的指针。第一个要删除的对象(例如临时对象?)将删除指针。当第二个对象被销毁时,它的析构函数将删除一个已经被删除的指针。

现在,如果您不喜欢注意 3 的规则,有一个更好的选择:避免使用原始指针。尝试改用shared_ptr。这些指针自己管理内存(例如,当不再使用对象时删除它)。包括在复制和删除副本的情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2021-07-20
    • 2018-12-23
    • 2021-09-20
    相关资源
    最近更新 更多