C++模板链表故障 我以前做过一些链接列表,概念对我来说都是有意义的,但是对于一个项目,我必须在C++中制作一个模板,我没有用过很多,而且我遇到了一些麻烦。请帮忙。我在这么简单的事情上花了太多时间

C++模板链表故障 我以前做过一些链接列表,概念对我来说都是有意义的,但是对于一个项目,我必须在C++中制作一个模板,我没有用过很多,而且我遇到了一些麻烦。请帮忙。我在这么简单的事情上花了太多时间,c++,linked-list,C++,Linked List,我已经有了一些list类,但问题就在这里。如果我调用 node1.getNext().show(); 那很好,但是如果我 node1.getNext().getNext().show(); 我被一个segfault内核甩了。这里怎么了?我尝试过多次更改getNext和getPrev返回值上的指针,但都没有成功。问这个问题我觉得很愚蠢,但我遇到了一些严重的麻烦。下面是我的节点类,后面是一个示例测试用例,它给出了一个segfault 节点h: template <class T> c

我已经有了一些list类,但问题就在这里。如果我调用

node1.getNext().show();
那很好,但是如果我

node1.getNext().getNext().show();
我被一个segfault内核甩了。这里怎么了?我尝试过多次更改getNext和getPrev返回值上的指针,但都没有成功。问这个问题我觉得很愚蠢,但我遇到了一些严重的麻烦。下面是我的节点类,后面是一个示例测试用例,它给出了一个segfault

节点h:

template <class T> class Node
{
 public:
  Node();
  Node(T value);
  void setPrev(Node<T> node);
  void setValue(T value);
  void setNext(Node<T> node);
  Node<T> getPrev();
  T getValue();
  Node<T> getNext();
  void show();
  ~Node() { }

 private:
  Node<T> *prev;
  Node<T> *next;
  T value;
};

//default construct                                                                                                                                                     
template <class T> Node<T>::Node() {
  this->prev = NULL;
  this->value = NULL;
  this->next = NULL;
};

//overloaded construct                                                                                                                                                  
template <class T> Node<T>::Node(T value) {
  this->prev = NULL;
  this->value = value;
  this->next = NULL;
}

template <class T> void Node<T>::setPrev(Node<T> node) {
  this->prev = &node;
}

template <class T> void Node<T>::setValue(T value) {
  this->value = value;
}

template <class T> void Node<T>::setNext(Node<T> node) {
  this->next = &node;
}

template <class T> Node<T> Node<T>::getPrev() {
  return this->prev;
}

template <class T> T Node<T>::getValue() {
  return this->value;
}

template <class T> Node<T> Node<T>::getNext() {
  return this->next;
}

template <class T>
void Node<T>::show() {
  cout << value << endl;
}
测试用例:

int main(int argc, char **argv) {

  typedef Node<int> IntNode;

  IntNode head(NULL);
  IntNode node1(23);
  IntNode node2(45);
  IntNode node3(77);
  IntNode tail(NULL);
  node1.setPrev(head);
  node1.setNext(node2);
  node2.setPrev(node1);
  node2.setNext(node3);
  node3.setPrev(node2);
  node3.setNext(tail);

  node1.show();
  node2.show();
  node3.show();

  cout << node1.getNext().getValue() << endl;
  cout << node1.getNext().getNext().getValue() << endl;
}

您应该将下一个/上一个成员存储为指针。设置上一个和下一个节点时,您将按值获取参数,从而进行复制

这意味着当您在node1.getNext.getNext.getNext.getValue中单步执行第二个.getNext时,您将遇到一个悬空指针,这就是代码失败的原因


手动添加节点是一件费力的事情,像std::list这样的工作方式是使用一个指向它所拥有的集合的开始和结束指针。当新节点被推到列表的前面或后面时,集合将创建节点、存储值并链接指针,以便下一个节点和/或遍历。

您应该将下一个/上一个成员存储为指针。设置上一个和下一个节点时,您将按值获取参数,从而进行复制

这意味着当您在node1.getNext.getNext.getNext.getValue中单步执行第二个.getNext时,您将遇到一个悬空指针,这就是代码失败的原因


手动添加节点是一件费力的事情,像std::list这样的工作方式是使用一个指向它所拥有的集合的开始和结束指针。当新节点被推到列表的前面或后面时,集合将创建节点、存储值并链接指针,以便下一个节点和/或遍历。

您需要通过引用而不是通过值传递值

执行node1.setNextnode1时,setNext会在堆栈上获取node1的副本,而不是在main中定义的变量。一旦setNext退出,存储在next中的地址将不再有效

首先,将函数setPrev和setNext重新定义为

template <class T> void Node<T>::setPrev(Node<T> &node) {
  this->prev = &node;
}

template <class T> void Node<T>::setNext(Node<T> &node) {
  this->next = &node;
}

这将修复您的直接故障。然而,您确实需要更多地考虑代码的设计以及按引用或按值传递时会发生什么,以正确编写代码并避免进一步的问题。

您需要按引用而不是按值传递值

执行node1.setNextnode1时,setNext会在堆栈上获取node1的副本,而不是在main中定义的变量。一旦setNext退出,存储在next中的地址将不再有效

首先,将函数setPrev和setNext重新定义为

template <class T> void Node<T>::setPrev(Node<T> &node) {
  this->prev = &node;
}

template <class T> void Node<T>::setNext(Node<T> &node) {
  this->next = &node;
}

这将修复您的直接故障。但是,您确实需要更多地考虑代码的设计以及按引用或按值传递时会发生什么,以便正确编写代码并避免进一步的问题。

最大的问题是,setNext和setPrev函数按值获取其参数,因此您可以获得在main中声明的节点的副本


如果要继续此操作,请通过引用或指针传递这些参数。通过指针传递可能更具语义意义,并可防止此类意外错误。

最大的问题是,setNext和setPrev函数按值获取其参数,因此您可以获得在main中声明的节点的副本


如果要继续此操作,请通过引用或指针传递这些参数。通过指针传递可能更具语义意义,并防止这种意外错误。

您是否将重新实现std::list作为一个学习项目?相反,在setPrev/setNext上,您应该只实现append,并在内部执行指针链接。否则,数据隐藏(即类的动机)是无效的,因为它是外部处理的“硬”逻辑。您是否将std::list重新实现为一个学习项目?相反,在setPrev/setNext上,您应该只实现append,并在内部执行指针链接。否则,数据隐藏,即类的动机,是无效的,是外部处理的“硬”逻辑。非常感谢。就像我说的,我以前只使用过C++几次,所以我对指针还不太满意,但是要处理它。再次感谢!非常感谢。就像我说的,我以前只使用过C++几次,所以我对指针还不太满意,但是要处理它。再次感谢!