gpt4 book ai didi

c++ - 在 C++ 中使用递归方法时双重释放或损坏 (fasttop)

转载 作者:行者123 更新时间:2023-11-28 00:32:47 30 4
gpt4 key购买 nike

我实现了一个 Stack 类并尝试利用该类来解决 Hanoi 问题。这是我的代码:

template<class Datatype>
class Node
{
public:
Node()
{
next = NULL;
prev = NULL;
}
Node* getNext()
{
return next;
}
Node* getPrev()
{
return prev;
}
Datatype* getData()
{
return &data;
}
void changeNext()
{
next = NULL;
}
void changeNext(Node& nextNode)
{
next = &nextNode;
}
void changePrev()
{
prev = NULL;
}
void changePrev(Node& prevNode)
{
prev = &prevNode;
}
Node* addNext(Node &);
Node* addPrev(Node &);
void nodeDel();
void addData(Datatype &);
private:
Node* next;
Node* prev;
Datatype data;
};

template<class Datatype>
class Stack
{
public:
Stack() : head( NULL )
{

}
virtual ~Stack()
{
Datatype temp;
while (pop(temp));
cout << "Stack released all spaces" << endl;
}
public:
virtual int push(Datatype &);
virtual int pop(Datatype &);
virtual Datatype* peek();
protected:
Node<Datatype> *head;
};
template <class Datatype>
int Stack<Datatype>::push(Datatype &new_data)
{
Node<Datatype> *pt_node = new Node<Datatype>;
if (pt_node == NULL)
return -1;

pt_node -> addData(new_data);

if (head == NULL)
head = pt_node;
else
{
pt_node -> addPrev(*head);
head = pt_node;
}

//cout << *(head -> getData()) << endl;

return 0;
}

template <class Datatype>
int Stack<Datatype>::pop(Datatype &pop_data)
{
if (head == NULL)
return 0;

pop_data = *(head -> getData());

if (head -> getNext() == NULL)
{
delete head;
head = NULL;
}
else
{
Node<Datatype>* temp = head;
head = head -> getNext();
delete temp;
}

return 1;
}

上面声明了 Stack 类 并实现了 pop()push() 函数。现在,我声明我的 Hanoi 类并实现功能。

class Hanoi
{
public:
Hanoi(int num) : a_tower(), b_tower(), c_tower()
{
deep = num;
int i;
for (i = num; i != 0; i --)
a_tower.push(i);
}
public:
void workdone(int, Stack<int>&, Stack<int>&, Stack<int>&);
void showret();
public:
Stack<int> a_tower;
Stack<int> b_tower;
Stack<int> c_tower;
int deep;
};

void Hanoi::workdone(int deep_num, Stack<int>& A, Stack<int>& B, Stack<int>& C)
{
int temp;
if (deep_num == 1)
{
A.pop(temp);
C.push(temp);
}
else
{
Hanoi::workdone(deep_num - 1, A, C, B);
A.pop(temp);
C.push(temp);
Hanoi::workdone(deep_num - 1, B, A, C);
}
}

void Hanoi::showret()
{
int temp;
while (c_tower.pop(temp) != 0)
cout << temp << endl;
}

这是我的测试代码:

int main()
{
Hanoi test(STACK_DEEP);
test.workdone(STACK_DEEP, test.a_tower, test.b_tower, test.c_tower);
test.showret();

return 0;
}

输出是:

*** glibc detected *** ./3_4: double free or corruption (fasttop): 0x090c0038 ***

我认为调用 ~Hanoi 时会发生此问题,但我真的不知道为什么会发生这种情况。

在这里,我发布了可以得到这个结果的完整代码:我的节点.h

#include <iostream>

using namespace std;

template<class Datatype>
class Node
{
public:
Node()
{
next = NULL;
prev = NULL;
}
Node* getNext()
{
return next;
}
Node* getPrev()
{
return prev;
}
Datatype* getData()
{
return &data;
}
void changeNext()
{
next = NULL;
}
void changeNext(Node& nextNode)
{
next = &nextNode;
}
void changePrev()
{
prev = NULL;
}
void changePrev(Node& prevNode)
{
prev = &prevNode;
}
Node* addNext(Node &);
Node* addPrev(Node &);
void nodeDel();
void addData(Datatype &);
private:
Node* next;
Node* prev;
Datatype data;
};

template<class Datatype>
class Stack
{
public:
Stack() : head( NULL )
{

}
virtual ~Stack()
{
Datatype temp;
while (pop(temp));
cout << "Stack released all spaces" << endl;
}
public:
virtual int push(Datatype &);
virtual int pop(Datatype &);
virtual Datatype* peek();
protected:
Node<Datatype> *head;
};

template <class Datatype>
Node<Datatype>* Node<Datatype>::addNext(Node<Datatype>& exi_node)
{
if (exi_node.getNext() == NULL)
{
changePrev(exi_node);
exi_node.changeNext(*this);
}
else
{
Node* next = exi_node.getNext();
changePrev(exi_node);
changeNext(*next);
exi_node.changeNext(*this);
next -> changePrev(*this);
}
return &exi_node;
}

template <class Datatype>
Node<Datatype>* Node<Datatype>::addPrev(Node<Datatype>& exi_node)
{
if (exi_node.getPrev() == NULL)
{
changeNext(exi_node);
exi_node.changePrev(*this);
}
else
{
Node* prev = exi_node.getPrev();
changePrev(*prev);
changeNext(exi_node);
exi_node.changePrev(*this);
prev -> changeNext(*this);
}
return &exi_node;
}

template<class Datatype>
void Node<Datatype>::nodeDel()
{
if (prev == NULL && next == NULL)
;
else if (prev == NULL)
{
Node* next = getNext();
next -> changePrev();
}
else if (next == NULL)
{
Node* prev = getPrev();
prev -> changeNext();
}
else
{
Node* next = getNext();
Node* prev = getPrev();
next -> changePrev(*prev);
prev -> changeNext(*next);
}
delete this;
return;
}

template <class Datatype>
void Node<Datatype>::addData(Datatype &new_data)
{
data = new_data;
}

template <class Datatype>
int Stack<Datatype>::push(Datatype &new_data)
{
Node<Datatype> *pt_node = new Node<Datatype>;
if (pt_node == NULL)
return -1;

pt_node -> addData(new_data);

if (head == NULL)
head = pt_node;
else
{
pt_node -> addPrev(*head);
head = pt_node;
}

//cout << *(head -> getData()) << endl;

return 0;
}

template <class Datatype>
int Stack<Datatype>::pop(Datatype &pop_data)
{
if (head == NULL)
return 0;

pop_data = *(head -> getData());

if (head -> getNext() == NULL)
{
delete head;
head = NULL;
}
else
{
Node<Datatype>* temp = head;
head = head -> getNext();
delete temp;
}

return 1;
}

template <class Datatype>
Datatype* Stack<Datatype>::peek()
{
if (head == NULL)
return NULL;
return (this->head)->getData();
}

3_4.h

#include <iostream>
#include "my_node.h"

using namespace std;

class Hanoi
{
public:
Hanoi(int num) : a_tower(), b_tower(), c_tower()
{
deep = num;
int i;
for (i = num; i != 0; i --)
a_tower.push(i);
}
public:
void workdone(int, Stack<int>&, Stack<int>&, Stack<int>&);
void showret();
public:
Stack<int> a_tower;
Stack<int> b_tower;
Stack<int> c_tower;
int deep;
};

void Hanoi::workdone(int deep_num, Stack<int>& A, Stack<int>& B, Stack<int>& C)
{
int temp;
if (deep_num == 1)
{
A.pop(temp);
C.push(temp);
}
else
{
Hanoi::workdone(deep_num - 1, A, C, B);
A.pop(temp);
C.push(temp);
Hanoi::workdone(deep_num - 1, B, A, C);
}
}

void Hanoi::showret()
{
int temp;
while (c_tower.pop(temp) != 0)
cout << temp << endl;
}

3_4.cpp

#include <iostream>
#include "3_4.h"

using namespace std;

#define STACK_DEEP 4

int main()
{
Hanoi test(STACK_DEEP);
test.workdone(STACK_DEEP, test.a_tower, test.b_tower, test.c_tower);
test.showret();

return 0;
}

我使用的命令:

g++ -Wall 3_4.cpp -o 3_4

最佳答案

代码比它需要的更复杂(和困惑),但错误归结为 Node::addPrev 的错误实现

最小的修复是将此函数的实现更改为:

    template <class Datatype>
Node<Datatype>* Node<Datatype>::addPrev(Node<Datatype>& exi_node)
{
exi_node.prev = this;
this->next = &exi_node;
return &exi_node;
}

适当的修复将涉及将 Stack 和 Node 类更改为更简单的实现——正如之前的评论者所提到的,它不需要是双链表。

关于c++ - 在 C++ 中使用递归方法时双重释放或损坏 (fasttop),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22183437/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com