C++构造函数似乎每次都返回指向相同对象的指针

4

我有一个Linked list类的简单实现,其中包含指向我定义的Node对象的指针。

insertHead函数创建一个新的Node并将其插入到头部。然而,每当我调用该函数时,构造函数似乎每次都返回指向同一个对象的指针。(我使用GDB检查过)

我在这里贴出代码片段。请问有什么地方不对吗?

void LinkedList::insertHead(int val){
  Node temp(val);
   if(head == NULL){
    head = tail = &temp;
  } else {
     temp.setNext(head);
     head = &temp;
  }
}

类定义:

class LinkedList{

  Node *head;
  Node *tail;
...

class Node{

  int val;
  Node *next;
...

Node::Node(int x){
  val = x;
  next = NULL;
}

3
你正在保存一个指向局部变量的指针,该变量在函数结束时失效并且无效。这个指针指向栈内存,所以它可能每次都是相同的。如果你需要动态分配对象,请使用new或一些独特或共享指针。 - Retired Ninja
1
“temp”正如你所命名的那样,具有自动生命周期:你正在存储指向已死对象的悬空指针。 - Quentin
2个回答

1
你需要在堆上分配节点,而不是栈上。我鼓励你阅读有关这两个的内容。如果支持(>c++11),请使用nullptr而不是NULL
void LinkedList::insertHead(int val){
  Node* temp = new Node(val);
  if(head == nullptr){
    head = tail = temp;
  } else {
     temp->setNext(head);
     head = temp;
  }
}

这还需要您使用delete正确清理节点,以避免内存泄漏。很可能需要向列表类添加自定义析构函数,类似于以下内容:
LinkedList::~LinkedList() {
  Node* node = head;
  while(node != nullptr) {
    Node* toDel = node;
    node = node->next;
    delete toDel;
  }
}

谢谢。我没有意识到 Node temp(val) 会创建一个自动变量。这就是我之前忽略的。 - Hina Jajoo

1
你不能将自动存储变量的地址分配并在其作用域之外使用,因为它已经超出了范围(未定义行为)。你需要在堆上动态分配空间给节点。
Node * temp = new Node(val);
if(head == NULL)
{
    head = tail = temp;
} else {
    temp.setNext(head);
    head = temp;
}

并在析构函数中释放所有节点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接