将对象与应等于 NULL 的 NULL 进行比较时出现分段错误

Segmentation fault when comparing an object to NULL which should equal NULL?

本文关键字:NULL 比较 错误 分段 对象      更新时间:2023-10-16

我在程序中遇到一个关键功能时遇到了一点麻烦,我已经在任何地方放置了错误测试行,并将其单调到一个if语句"

template <typename Item>
bool BTNode<Item>::isNull(string leftOrRight)
{
    std::cout<<"Is NULL test outer."<<endl;
    bool returnNullTest = true;
    if (leftOrRight == "left")
    {
        std::cout<<"Is NULL test inner 1."<<endl;
        if (left != NULL)
        {
            returnNullTest = false;
        }
    }
    else if (leftOrRight == "right") //.c_str()
    {
        std::cout<<"Is NULL test inner 2."<<endl;
        if (right != NULL)
        {
            returnNullTest = false;
        }
    }
    std::cout<<"NULL TEST FINISHED."<<endl;
    return returnNullTest;
}

这是输出:

Is NULL test outer.
Is NULL test inner 2.
Segmentation fault (core dumped)

这是"左"和"右"的定义:

BTNode<Item>* left;
BTNode<Item>* right;

在BTNode的构造函数中,"左"和"右"定义为:

left = NULL;
right = NULL;

有没有人知道我哪里出了问题,我已经尝试过这条线

if (left == NULL)

if (right == NULL)

布尔值切换,但我得到了同样的错误。

这是"BTNode.h"

#ifndef matt_BTNode
#define matt_BTNode
#include <cstdlib>
namespace mattassign3{
template <typename Item>
class BTNode
{
    private:
    Item* data;
    BTNode<Item>* left;
    BTNode<Item>* right;
    public:
    BTNode();
    BTNode(Item* startingData);
    ~BTNode();
    BTNode<Item>* getLeft();
    BTNode<Item>* getRight();
    Item* getData();
    bool isNull(string leftOrRight);
    void setLeft(BTNode<Item>* leftToSet);
    void setRight(BTNode<Item>* rightToSet);
    void printInclData();
    float comparableNumber();
    string comparableString();
};
}
#include "BTNode.template"
#endif
很可能

this是无效指针。该函数在第一次访问 this 的成员时崩溃。尝试将this与第一封邮件一起打印。

访问"right"时崩溃的事实是调用堆栈中更高位置的错误症状。具体来说,在到达程序的这一点之前,您必须已经做了类似的事情,例如

BNode* node = something->getRight();
node->isNull();

您需要提醒自己,在isNull函数中,rightleft是成员变量。它们在内存中的位置是相对于它们所属的BNode实例而言的,它们不仅仅是一些局部变量(这是许多程序员选择用前缀"m_"来区分成员变量的另一个很好的原因,例如"m_left","m_right")。

如果您调用"isNull"的"BNode*"指针不好,那么

记住当您说
if(left != NULL)

您正在访问 *(此 + 4 个字节)。您正在"逃脱"访问"左",但不幸的是,"右"位于导致崩溃的某种内存边界的另一侧。

确保:您的构造函数为这些指针分配默认值,您在取消引用之前检查来自 getLeft() 和 getRight() 的返回值,您的复制构造函数不会复制这些值(这意味着有两个节点认为它们在树中的同一位置),并且您的析构函数断言节点是否未取消链接或取消链接节点。