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

时间:2013-11-08 08:35:02

标签: c++

我在我的程序中遇到一个关键功能有点麻烦,我已经把bug测试线放到了各处,然后把它单个化为单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)

这是'left'和'right'的定义:

BTNode<Item>* left;
BTNode<Item>* right;
BTNode“left”和“right”的构造函数中的

定义为:

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

2 个答案:

答案 0 :(得分:3)

很可能this是无效指针。该函数在第一次访问this成员时崩溃。尝试打印this以及第一条消息。

答案 1 :(得分:2)

当您访问“正确”时崩溃的事实是您的调用堆栈中存在更高错误的症状。具体来说,在你的程序中到达这一点之前,你必须做过类似的事情,例如

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

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

如果你正在调用“isNull”的“BNode *”指针是坏的,那么当你说

时有助于记住
if(left != NULL)

您正在访问*(此+ 4个字节)。你正在“离开”访问“左”,但不幸的是,“右”在某种内存边界的另一边导致你的崩溃。

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