二进制搜索树的未处理异常

时间:2015-05-30 20:36:13

标签: c++ visual-c++ tree

我不知道导致它的原因。你们能帮助我吗?自从上次人们抱怨因为我只应该发布MCVE而不是所有的源代码。我会发布(我认为)与问题相关的内容。它基本上是二进制搜索树,未处理的异常与BST类的add方法有关。

Node.h

swapElementsAt :: Int -> Int -> [a] -> [a]
swapElementsAt i j xs = let elemI = xs !! i
                            elemJ = xs !! j
                            left = take i xs
                            middle = take (j - i - 1) (drop (i + 1) xs)
                            right = drop (j + 1) xs
                    in  left ++ [elemJ] ++ middle ++ [elemI] ++ right

Node.cpp

ReservedSignChar = '®';
x = ReservedSignChar.encode('utf-8');
print(x);

BST.h

#ifndef NODE_H
#define NODE_H

#include "Button.h"

class Node
{
private:

    int key;
    Node* left;
    Node* right;
    Button nextPlay;
    bool used;

public:

    Node();
    Node(int k, int x, int y);

    void setLeft(Node* n);
    Node* getLeft();
    void setRight(Node* n);
    Node* getRight();
    Button getPlay();
    int getKey();
    void setUsed();
    bool getUsed();

};

#endif

BST.cpp

#include "Node.h"

Node::Node()
{
    key = 0;
    left = NULL;
    right = NULL;
    //nextPlay = NULL;
    used = false;
}

Node::Node(int k, int x, int y)
{
    key = k;
    left = NULL;
    right = NULL;
    nextPlay.getPosition()->x = x;
    nextPlay.getPosition()->y = y;
    used = false;
}

void Node::setLeft(Node* n)
{
    left = n;
}

Node* Node::getLeft()
{
    return left;
}

void Node::setRight(Node* n)
{
    right = n;
}

Node* Node::getRight()
{
    return right;
}

Button Node::getPlay()
{
    return nextPlay;
}

int Node::getKey()
{
    return key;
}

void Node::setUsed()
{
    used = true;
}

bool Node::getUsed()
{
    return used;
}

当我运行程序时,未处理的异常指向:

#ifndef BST_H
#define BST_H

#include "Node.h"

class BST
{
private:

    Node* root;

    bool add(Node* n, int k, int x, int y);
    int remAll(Node* n);
    Button get(Node* n);

public:

    BST();
    ~BST();

    bool add(int k, int x, int y);
    int remAll();
    Button get();

};

#endif

在BST的添加方法中使用。

3 个答案:

答案 0 :(得分:3)

如果您向空BST添加注释,则执行将是:

bool BST::add(int k, int x, int y)
{
    return add(root, k, x, y);
}

rootNULL时,add(root, k, x, y)会发生以下情况:

   bool success;
   if (n = NULL) {      // <=== OUCH !!! you set n to NULL if if wasn't 
       ...              // this is ignored because the condition is always NULL
   }
   else {               // so the else part is executed       
       if (k == n->getKey()) {  //  <======OUCH !!! remember n is NULL 

所以在这个阶段,由于两个错误(参见上面的OUCH注释),你取消引用空指针n。这会导致您的段错误。

备注:从技术上讲,由于getKey()不是虚拟的,实际上可能会调用该函数this为NULL,因此仅在{{1}时才会触发段错误访问。但这取决于实现。

如何解决?

首先,纠正节点为NULL的情况:

key

但这还不够。您的递归算法期望以下语句修改树中的指针。不幸的是,实际上它只修改了一个本地指针变量,并让树原样:

if (n == NULL)   // == instead of =

只有当 n = new Node(k, x, y); // store the newly created node, but... n is local 成为对树中原始指针的引用时,您的方法才有效。您可以通过更改函数的签名来实现此目的:

n

答案 1 :(得分:1)

问题似乎是在创建节点时。您正在通过add方法而不是引用的值传递指针。函数签名应为bool BST::add(Node*& n, int k, int x, int y)。同时将n = NULL更改为n == NULL进行比较,而不是asign。

希望这有帮助!

答案 2 :(得分:1)

经常建议的避免错误的方法

if (n = NULL) {

是尝试切换你的风格

if (NULL == n) {

这会导致编译器给出错误。 L.H.S操作数不再是l值,并且对于&#39; =&#39;而不是&#39; ==&#39;,防止您意外地执行此操作。我在职业生涯的早期几次犯过这个错误并永久性地转换。