尝试在C ++中使用NULL指针时,不会发生分段错误

时间:2014-03-03 02:35:48

标签: c++ segmentation-fault

我定义了两个类:

template<class Datatype>
class Node
{
    public:
        Node()
        {
            next = NULL;
            prev = NULL;
        }
        Node* getNext()
        {
            return next;
        }
        Node* getPrev()
        {
            return prev;
        }
        Datatype* getData()
        {
            return &data;
        }
        void changeNext()
        {
            next = NULL;
        }
        void changeNext(Node& nextNode)
        {
            next = &nextNode;
        }
        void changePrev()
        {
            prev = NULL;
        }
        void changePrev(Node& prevNode)
        {
            prev = &prevNode;
        }
        Node* addNext(Node &);
        Node* addPrev(Node &);
        void nodeDel();
        void addData(Datatype &);
    private:
        Node* next;
        Node* prev;
        Datatype data;
};

template<class Datatype>
class Stack
{
    public:
        Stack() : node()
        {
            ;
        }
        int push(Datatype &);
        Datatype pop();
        Datatype* peek();
    private:
        Node<Datatype> node;
};

我试着做一些调试。我使用函数调用将数据包推入此堆栈:

template <class Datatype>
int Stack<Datatype>::push(Datatype &new_data)
{
    Node<Datatype> *pt_node = new Node<Datatype>;
    if (pt_node == NULL)
        return -1;

    Datatype *pt_data;

    pt_data = (this -> node).getData();
    pt_node -> addData(*pt_data);   
    (this -> node).addData(new_data);

    pt_node -> addNext(this -> node);

    cout << ((node.getNext())) << endl;

    return 0;
}

我打印出节点的下一个指针。它应该是NULL,因为它是堆栈中唯一的数据包,结果证明了这一点。我调用此函数时的输出为0。 但是,我稍微改变了push函数的cout指令:

cout << ((node.getNext()) -> getData()) << endl;

我尝试打印出下一个节点的数据。显然没有什么应该存在,因为该节点不存在,并且我已证明node.getNext()返回0。奇怪的是这里没有发生分段错误,它确实有输出0x8。我不知道怎么会发生这种情况。

2 个答案:

答案 0 :(得分:5)

getData返回指向成员的指针;所以它不需要解除引用this,只需添加一个偏移量。这就是为什么即使this为空也不会出现细分错误的原因。

当然,它仍然是未定义的行为。

答案 1 :(得分:2)

取消引用NULL指针是未定义的行为,这实际上意味着任何事情都可能发生,它不能保证崩溃(虽然操作系统可能会因为自身安全而崩溃你的应用程序)这是高度依赖于实现的,并且这样的代码不应该存在于你的申请。

引用标准

  

注意:特别是,空引用不能存在于明确定义的中   程序,因为创建这样的引用的唯一方法是   将它绑定到通过解除引用空指针获得的“对象”,   这会导致未定义的行为。如9.6中所述,参考   不能直接绑定到位字段。 - 注意