为双向链接列表在Destructor中指定给RtlvalidateHeap的无效地址

问题描述 投票:0回答:1

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

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个回答
0
投票

虽然您的代码不足以确定结论,只是查看症状和破坏因素,但是很可能您不尊重rule of 3

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

为什么?

  • 您的课堂上有一个指针Next
  • 以某种方式分配内存并将地址放在该指针中(因为如果不这样做,就不会在最后删除指向的对象
  • 如果没有复制结构和复制分配,则无论何时复制List元素,都将照原样复制其指针。要删除的第一个对象(例如临时对象?)将删除指针。当第二个对象被销毁时,其析构函数将删除已经删除的指针。

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

© www.soinside.com 2019 - 2024. All rights reserved.