删除双向链接列表时程序崩溃

时间:2019-06-14 05:07:34

标签: c++ cygwin doubly-linked-list chess stack-dump

我正在用C ++创建一个国际象棋程序,该程序使用一个双向链接列表树来存储移动生成的结果。实际上,它是双向链接列表的双向链接列表,因为我需要一个列表树来存储每个给定板位的所有可能动作。到目前为止,我的实现工作正常,除了复制分配。

我正在尝试实现一个赋值运算符,以将数据从一个列表复制到另一个列表。到目前为止,它仍然有效,但是删除原始列表时(超出范围时)测试用例崩溃。我要复制的列表是树的内部维度上的列表,称为nextList。外部维度上的外部列表称为gameTree

我必须能够将一个列表复制到另一个列表中,因为我必须复制副本以过滤移动(以过滤掉使自己的国王受阻的移动)。

我不确定是否应该在运算符函数中使用指针,因为重点不是复制指向列表的指针而是复制列表本身。不过,它似乎可以使用我编写的代码正确地复制(崩溃除外)。

gameTree类声明:

class gameTree {
public:
    class Board board;          // current board position
    class nextList *headPtr;    // pointer to the first list in the tree
    class nextList *tailPtr;    // pointer to the last list in the tree
    class Move move;            // the move we are making
    int treeSize = 0;
    nextList *currentPtr;

    void insertList();          // create an empty list
    void removeList();          // remove first list on the tree
    int getSize();              // returns number of lists in tree
    nextList* getList(int);     // returns a pointer to the list at the given index

    void printTree();           // recursively prints the tree

    gameTree();                 //constructor
    ~gameTree();                //destructor
};

nextList类声明:

class nextList {
public:
    class nextList *nextListPtr;    // pointer to the next list down
    class nextList *prevListPtr;    // pointer to the next list up
    int index;                      // index of the current list

    class nextNode {
        class Move move;            // move we are making
        class nextNode * prevPtr;   // pointer to the next element on the list
        class nextNode * nextPtr;   // pointer to the previous element on the list
        int index;                  // index of the current move

        nextNode();                 // constructor
        ~nextNode();
        void printNode();           // prints the node

        friend class nextList;
        void swap(nextNode&, nextNode&);            // swap function
        nextNode& operator=(nextNode);
    };

    class nextNode *headPtr;        // pointer to the first element on the list
    class nextNode *tailPtr;        // pointer to the last element on the list

    void insertNode(Move);          // insert a node at the end of the list
    Move removeNode();              // remove node from the end of the list and return move
    Move readNode(int);             // returns the move at the index in the list

    int getSize();                  // returns size of list
    bool findNode(Move);            // returns true if node with matching move is found
    void printList();               // prints the list

    nextList();                     // constructor
    ~nextList();                    // destructor

    nextList& operator=(nextList*);
    void swap(nextList&, nextList&);
};

移动结构:

struct Move {
    int fromX;
    int fromY;
    int toX;
    int toY;
    int score;
};

nextList赋值运算符:

nextList& nextList::operator=(nextList *other) {
    nextNode *otherPtr;
    otherPtr = other->headPtr;

    while (otherPtr != nullptr) {
        //copy element to *this
        this->insertNode(otherPtr->move);
        otherPtr = otherPtr->nextPtr;
    }

    std::cout << "returning *this..." << std::endl;
    return *this;
}

nextList析构函数:

nextList::~nextList() {
    nextNode *tempPtr;

    while (headPtr != nullptr) {
        //delete element
        tempPtr = headPtr->nextPtr;
        delete headPtr;
        headPtr = tempPtr;
    }
    tailPtr = nullptr;
    std::cout << "list deleted" << std::endl;
}

测试案例:

#include <string>
#include "gametree.h"
#include "nextlist.h"
#include "move.h"

using namespace std;

void listTest();

int main() {
    cout << "entered main" << endl;

    listTest();

    cout << "Press ENTER to continue..." << endl;
    cin.get();
    return 0;
}

void listTest() {
    nextList list;
    Move move;
    move.fromX = 0;
    move.fromY = 1;
    move.toX = 0;
    move.toY = 3;

    list.insertNode(move);
    list.insertNode(move);

    nextList list2;
    list2 = list;

    list.printList();
    list2.printList();
    cout << "breakpoint" << endl;
}

运行时,程序输出为:

entered main
0x600074390 0 0x600074350 node: [0 1 0 3]
0x600074350 0x600074390 0 node: [0 1 0 3]

0x600074390 0 0x600074350 node: [0 1 0 3]
0x600074350 0x600074390 0 node: [0 1 0 3]

breakpoint
list deleted
      3 [main] main 4168 cygwin_exception::open_stackdumpfile: Dumping stack trace to main.exe.stackdump

我确实注意到其中一个列表从未删除(或至少从未到达cout语句)。

顺便说一下,打印功能如下:

printList():

void nextList::printList() {
    nextNode *newPtr;
    newPtr = headPtr;
    int count = 0;

    if (newPtr == nullptr) std::cout << "List is empty!" << std::endl;
    else {
        while (count < 10) {
            std::cout << newPtr << " " << newPtr->prevPtr << " " << newPtr->nextPtr << " ";
            std::cout << "node: ";
            newPtr->printNode();
            std::cout << std::endl;

            newPtr = newPtr->nextPtr;
            count++;

            if (newPtr == nullptr) break;   // found end of list
        }
    }

    std::cout << std::endl;
}

printNode():

void nextList::nextNode::printNode() {
    std::cout << "[" << move.fromX << " " << move.fromY << " " << move.toX << " " << move.toY << "]";
}

0 个答案:

没有答案