" free(): invalid pointer:" 8谜题BFS

" free(): invalid pointer:" 8-puzzle BFS

本文关键字:谜题 BFS pointer invalid free      更新时间:2023-10-16

我正在尝试编写一个广度的第一个搜索程序来解决8个式嘴。当我运行以下代码时,我会收到以下错误:

*`/home/a.out'中的错误:free((:无效指针:0x000000000001f81430 *
中止

我很确定问题是 this 指针以及我如何存储父节点的使用情况。有帮助吗?

 #include <iostream>
 #include <string>
 #include <iostream>     
 #include <algorithm>    
 #include <vector>       
 #include <queue>
 using namespace std;
 class Node {
 public:
vector<Node> children;
vector<int> puzzle;
vector<int> goal = {1, 2, 3, 4, 5, 6, 7, 8, 0};
Node *parent;
Node(vector<int> _puzzle, Node *_parent){   // constructor for node
    puzzle=_puzzle;
    parent=_parent;
}
void moveUp(){    //function to move up
    int zPos = findZero();
    vector<int> temp = puzzle;
    if ( zPos != 0 || zPos != 1 || zPos != 2 )
    std::swap(temp[zPos], temp[zPos-3]);
    Node child = Node(temp, this);
    children.push_back(child);      
}
void moveDown(){    //function to move down
    int zPos = findZero();
    vector<int> temp = puzzle;
    if ( zPos != 6 || zPos != 7 || zPos != 8 )
    std::swap(temp[zPos], temp[zPos+3]);
    Node child = Node(temp, this);
    children.push_back(child); 
}
void moveRight(){    //function to move right
    int zPos = findZero();
    vector<int> temp = puzzle;
    if ( zPos != 2 || zPos != 5 || zPos != 8 )
    std::swap(temp[zPos], temp[zPos+1]);
    Node child = Node(temp, this);
    children.push_back(child);
}

void moveLeft(){     //function to move left
    int zPos = findZero();
    vector<int> temp = puzzle;
    if ( zPos != 0 || zPos != 3 || zPos != 6 )
    std::swap(temp[zPos], temp[zPos-1]);
    Node child = Node(temp, this);
    children.push_back(child); 
}
void printPuzzle() {    //function to print the puzzle
    int count = 0;
    for (auto i: puzzle) {
    if ( count % 3 == 0)
    std::cout << std::endl;
    std::cout << i << ' ';
    count++;   
}
}
int findZero(){    // function to find the location of zero
    std::vector<int>::iterator it;
    it = find (puzzle.begin(), puzzle.end(), 0);
    auto z = std::distance(puzzle.begin(), it);
    return (int)z;
}
bool isGoal(){  //function to check if goal state is reached
    bool goalFound = false;
    if(puzzle == goal)
    goalFound = true;
    return goalFound;
}
};

bool contains(std::queue<Node> q, Node n){   // checks repeated nodes
    std::queue<Node> tempQ = q;
    bool exist = false;
    while (!tempQ.empty()){
        if (tempQ.front().puzzle == n.puzzle)
        exist = true;
        tempQ.pop();
    }
    return exist;
}
int main()
{
std::vector<int> initial = {3, 5, 8, 1, 0, 4, 2, 7, 6};
Node init = Node(initial, NULL);
std::queue<Node> openList;
std::queue<Node> closedList;
openList.push(init);
bool goalFound = false;
while(!openList.empty() && !goalFound){
    Node currentNode = openList.front();
    closedList.push(currentNode);
    openList.pop();       
    currentNode.moveUp();
    currentNode.moveDown();
    currentNode.moveRight();
    currentNode.moveLeft();
    for (auto i: currentNode.children){
        Node currentChild = i;
        if (currentChild.isGoal()){
            std::cout << "Goal Found." << endl;
            goalFound = true;           
        }
        if (!contains(openList, currentChild) && !contains(closedList, currentChild))
            openList.push(currentChild); 
    }      
}
}

现在,我只专注于寻找目标。我尚未实施目标的道路并打印最终解决方案。

if (zPos != 0 || zPos != 1 || zPos != 2)

应该是

if (zPos != 0 && zPos != 1 && zPos != 2)

和同上的兄弟姐妹在另一个举动中发挥作用。

tl; DR解释:

moveUp

if (zPos != 0 || zPos != 1 || zPos != 2)

无法做您想做的事。由于zPos不能同时是0、1和2,因此身体将始终执行。例如,如果zPos为零,则

if (0 != 0 || 0 != 1 || 0 != 2)
    false  || true   

一个true就足够了。

这意味着

std::swap(temp[0], temp[0-3]);

将交换0,-3,并脱离界限。当您将内存弄乱到界限之外时,可能会发生各种怪异,而我认为这次您正在覆盖vector的存储缓冲区的一些书籍保存。vector被释放后,Kablamo,Kablamo!