BST.cpp的重载移动分配运算符:
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
看一下我评论过的cout << root << endl部分。当该段代码运行时,它会打印出除00000000以外的地址。这似乎并没有正确删除它们。
这是一个代码,其中删除了调用对象的BST(所有分支),然后窃取了其他BST的树。移动分配运算符。 但是为什么不打印nullptr而是打印另一个地址?似乎它没有被正确删除。
在这里供参考:
这是正在运行的测试驱动程序的屏幕截图:click here to see.
Main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
int main()
{
runTest();
cout << endl << endl;
system("Pause");
return 0;
}
Test.h
#include "BST.h"
void runTest() {
cout << "--------------------------------------------------------------------" << endl;
cout << "Binary Search Tree Test Driver" << endl;
cout << "--------------------------------------------------------------------" << endl;
// Initialization:
BST bst1;
// Traversal when there are no elements in the tree:
cout << "BST traversal when there are no elements within the tree (bst1): " << endl;
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting one element into the tree recursively and non-recursively (bst1): " << endl;
bst1.insert(21);
bst1.preorderTraversal();
cout << endl;
bst1.insert(69);
bst1.preorderTraversal();
cout << endl;
cout << "BST, inserting duplicate elements into the tree recursively (bst1): " << endl;
bst1.insert(32);
bst1.insert(32);
bst1.preorderTraversal();
cout << endl;
cout << "BST using the function destroyTree (bst1): " << endl;
bst1.destroyTree();
bst1.preorderTraversal();
cout << endl;
cout << "BST copy constructor by copy constructing bst1 (bst2): " << endl;
bst1.insert(21);
bst1.insert(69);
BST bst2(bst1);
bst2.preorderTraversal();
cout << endl;
cout << "BST move constructor by move constructing bst1 (bst3): " << endl;
BST bst3 = move(bst1);
bst3.preorderTraversal();
cout << endl;
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 has no elements in its tree: " << endl;
bst1.destroyTree();
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
bst1.destroyTree();
bst2.destroyTree();
cout << "BST move assignment operator by move assigning bst2 (bst1) when bst1 already has some elements in its tree: " << endl;
bst1.insert(21);
bst1.insert(105);
bst1.insert(18);
bst1.insert(16);
bst1.insert(7);
bst1.insert(19);
bst1.insert(109);
bst1.insert(125);
bst1.insert(101);
bst2.insert(691);
bst1 = move(bst2);
bst1.preorderTraversal();
cout << endl;
}
BST.h
#ifndef BST_H
#define BST_H
#include <string>
#include <iostream>
#include <stack>
using namespace std;
class Node
{
friend class BST;
public:
Node() : data(0), rlink(nullptr), llink(nullptr) {}
~Node() {}
private:
int data;
Node *rlink, *llink;
};
class BST
{
public:
BST();
BST(const BST& otherBST);
BST(BST&& otherBST);
void insert(int item);
void insertNonRecursive(int item);
void preorderTraversal() const;
// BST& operator=(const BST& otherBST);
BST& operator=(BST&& otherBST);
void destroyTree();
~BST();
private:
Node * root; // Pointer to the root.
void copyConstructor(const Node *p);
void insert(Node* &p, Node *newNode);
void preorderTraversal(const Node *p) const;
void destroyTree(Node *&p);
};
#endif
BST.cpp
#include "BST.h"
BST::BST() : root(nullptr) {}
BST::BST(const BST& otherBST) {
copyConstructor(otherBST.root);
}
BST::BST(BST&& otherBST) {
root = move(otherBST.root);
otherBST.root = nullptr;
}
void BST::copyConstructor(const Node *p) {
if (p != nullptr) {
insert(p->data);
copyConstructor(p->llink);
copyConstructor(p->rlink);
}
}
void BST::insert(int insertItem)
{
Node *newNode = new Node;
newNode->data = insertItem;
insert(root, newNode);
}
void BST::insert(Node* &p, Node *newNode)
{
if (p == nullptr)
p = newNode;
else if (p->data > newNode->data)
insert(p->llink, newNode);
else
insert(p->rlink, newNode);
}
void BST::insertNonRecursive(int item) {
if (root == nullptr) {
root = new Node();
root->data = item;
}
else {
Node *current = root;
bool searching = true;
while (searching) {
if (item > current->data && current->rlink != nullptr) {
current = current->rlink;
}
else if (item < current->data && current->llink != nullptr) {
current = current->llink;
}
else if (item == current->data) {
cerr << "The item to insert is already in the list, duplicates are not allowed." << endl;
searching = false;
}
else {
if (item > current->data) {
current->rlink = new Node();
current->rlink->data = item;
}
else {
current->llink = new Node();
current->llink->data = item;
}
searching = false;
}
}
}
}
void BST::preorderTraversal() const {
if (root == nullptr)
cerr << "There is no tree.";
else
{
preorderTraversal(root);
}
}
void BST::preorderTraversal(const Node *p) const {
if (p != nullptr) {
cout << p->data << " ";
preorderTraversal(p->llink);
preorderTraversal(p->rlink);
}
}
BST& BST::operator=(BST&& otherBST) {
if (this != &otherBST) {
if (root) {
stack <Node*> nodeStack;
nodeStack.push(root);
Node *currentNode = nullptr;
while (!nodeStack.empty()) {
currentNode = nodeStack.top();
nodeStack.pop();
if (currentNode->rlink) {
nodeStack.push(currentNode->rlink);
}
if (currentNode->llink) {
nodeStack.push(currentNode->llink);
}
delete currentNode;
currentNode = nullptr;
}
cout << root << endl; // This is where it seems like root is not being deleted correctly/nullptr'd.
}
root = move(otherBST.root);
otherBST.root = nullptr;
}
else {
cerr << "ERROR: Cannot assign to self." << endl;
}
return *this;
}
void BST::destroyTree(Node* &p)
{
if (p != nullptr)
{
destroyTree(p->llink);
destroyTree(p->rlink);
delete p;
p = nullptr;
}
}
void BST::destroyTree()
{
destroyTree(root);
}
BST::~BST()
{
destroyTree(root);
}
答案 0 :(得分:0)
我认为您提到的行很好,没有泄漏任何内容。只是指针没有分配给NULL。 在下面的示例中,您可能正在期望pA为NULL
int *pA = new int;
int *pB = pA;
delete pB;
pB=NULL;
printf("pA=0x%p, pB=0x%p", pA,pAB);
请注意,即使pA指向的东西(现在是悬空的指针)也没有泄漏。
要获得所需的行为,可以在完成压入堆栈后将根设置为NULL。