我定义了两个类:
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。我不知道怎么会发生这种情况。
答案 0 :(得分:5)
getData
返回指向成员的指针;所以它不需要解除引用this
,只需添加一个偏移量。这就是为什么即使this
为空也不会出现细分错误的原因。
当然,它仍然是未定义的行为。
答案 1 :(得分:2)
取消引用NULL指针是未定义的行为,这实际上意味着任何事情都可能发生,它不能保证崩溃(虽然操作系统可能会因为自身安全而崩溃你的应用程序)这是高度依赖于实现的,并且这样的代码不应该存在于你的申请。
引用标准
注意:特别是,空引用不能存在于明确定义的中 程序,因为创建这样的引用的唯一方法是 将它绑定到通过解除引用空指针获得的“对象”, 这会导致未定义的行为。如9.6中所述,参考 不能直接绑定到位字段。 - 注意