指针、静态对象和新对象

Pointers and static and new objects

本文关键字:对象 新对象 静态 指针      更新时间:2023-10-16

首先,如果这是一个重复的问题,请道歉。我只是在学习C++,可能不知道正确的搜索词来查找我确信已经被问到的内容。

无论如何,我通过在HackerBank上学习30天的代码来自学C++。然而,当被要求为LinkedList实现insert方法时,我遇到了一个似乎无法解决的障碍。从概念上讲,我知道需要做什么,但从语法上来说,我遇到了一个问题。

下面是我的代码,包括调试打印输出。似乎正在发生的事情是,new_node一直被放在内存中的同一个位置,无论它在哪个循环迭代中。我如何确保它在内存中有一个新的位置?无论我是否将new_node声明为static,我似乎都得到了相同的行为。

这是代码:

#include <iostream>
#include <cstddef>
using namespace std;    
class Node
{
    public:
        int data;
        Node *next;
        Node(int d){
            data=d;
            next=NULL;
        }
};
class Solution{
    public:
    /// ----- MY CODE BEGINS HERE:
      Node* insert(Node *head,int data)
      {
          cout << "----------" << endl;
          cout << data << endl;
          int i = 0;
          if (head){
              Node *curr = head;
              Node *next = curr->next;
              while(next){
                  cout << data << "," << i << ": " << curr << "," << curr->next 
                   << "," << curr->data << endl;
                  i++;
                  curr = curr->next;
                  next = curr->next;
              }
              cout << data << "," << i << ": " << curr << "," << curr->next 
                   << "," << curr->data << endl;
              static Node new_node = Node(data);
              curr->next = &new_node;
              cout << " ***  Adding " << data << " at " << curr->next
                   << " and next points to: " << (curr->next)->next << endl;
              return head;
          }
          else{
              static Node new_head = Node(data);
              cout << " ***  Adding " << data << " at " << &new_head
                   << " and next points to: " << new_head.next << endl;
              return &new_head;
          }
      }
      // ------- MY CODE ENDS HERE
      void display(Node *head)
      {
          Node *start=head;
          while(start)
          {
              cout<<start->data<<" ";
              start=start->next;
          }
      }
};
int main()
{
    Node* head=NULL;
    Solution mylist;
    int T,data;
    cin>>T;
    while(T-->0){
        cin>>data;
        head=mylist.insert(head,data);
    }   
    mylist.display(head);
}

当我用(4,2,3,4,1)的样本输入运行这个程序时,我得到以下结果:

----------
2
 ***  Adding 2 at 0x6022e0 and next points to: 0
----------
3
3,0: 0x6022e0,0,2
 ***  Adding 3 at 0x7fff3ddc1d80 and next points to: 0
----------
4
4,0: 0x6022e0,0x7fff3ddc1d80,2
4,1: 0x7fff3ddc1d80,0,3
 ***  Adding 4 at 0x7fff3ddc1d80 and next points to: 0x7fff3ddc1d80
----------
1
1,0: 0x6022e0,0x7fff3ddc1d80,2
1,1: 0x7fff3ddc1d80,0x7fff3ddc1d80,4
1,2: 0x7fff3ddc1d80,0x7fff3ddc1d80,4
1,3: 0x7fff3ddc1d80,0x7fff3ddc1d80,4
1,4: 0x7fff3ddc1d80,0x7fff3ddc1d80,4
1,5: 0x7fff3ddc1d80,0x7fff3ddc1d80,4

并且这种情况一直持续到分段故障ebcause陷入无限循环。。。

你知道new_node为什么一直被放在同一个内存位置吗(有没有static)?这甚至不是主要问题,我完全没有抓住要点吗?提前感谢!

--C++新手。


编辑:建议的复制品并不能完全解决这里的问题。我的问题不是理解指针和引用之间的区别,而是之间的区别

Node node_1 = Node(data);
static node_2 = Node(data);
node_3 = new Node(data);

由于在撰写问题时我不知道new运算符(显然!),我不知道(a)搜索该运算符或(b)在标题中包含该术语。为了清晰起见,对标题进行了编辑,并为未来的读者提供了此编辑。

当您声明一个变量static时,该变量只有一个副本。它是在您第一次执行声明时创建的,将来对该函数的调用会重用相同的数据。所以每次使用new_node时,都是同一个节点。

您需要使用new运算符来分配动态数据。正如操作符名称所暗示的,每次使用它时都会创建一个新对象。当你向类中添加remove()操作时,它将使用delete来释放内存。

  Node* insert(Node *head,int data)
  {
      cout << "----------" << endl;
      cout << data << endl;
      int i = 0;
      if (head){
          Node *curr = head;
          Node *next = curr->next;
          while(next){
              cout << data << "," << i << ": " << curr << "," << curr->next 
               << "," << curr->data << endl;
              i++;
              curr = curr->next;
              next = curr->next;
          }
          cout << data << "," << i << ": " << curr << "," << curr->next 
               << "," << curr->data << endl;
          Node *new_node = new Node(data);
          curr->next = new_node;
          cout << " ***  Adding " << data << " at " << curr->next
               << " and next points to: " << (curr->next)->next << endl;
          return head;
      }
      else{
          Node *new_head = new Node(data);
          cout << " ***  Adding " << data << " at " << &new_head
               << " and next points to: " << new_head->next << endl;
          return new_head;
      }
  }

您使用一个静态变量。这些只创建一次,并且对于每个函数调用都是相同的!您的意图是始终创建一个新的Node,因此这些变量不是静态的!

试用

Node* new_head = new Node(data);
return new_head;
// as well as
Node* new_node = new Node(data);
curr->next = new_node;

所有节点都必须在免费存储中创建(使用new),否则在函数结束时会被清理。这意味着您总是引用不存在的变量,这是内存损坏。您还必须提供一个析构函数来删除新的节点。有关更多信息,请阅读有关变量寿命的信息。

进一步说明:

  • 使用nullptr
  • std::list或std::linked_list是列表的容器(我知道,你想学习,但看看它们)
  • 你的类都是公共的->你可以使用一个结构,因为它是相同的,但默认是公共的访问说明符
  • 使用uniqueptr作为所有权(这有点高级,但要尽早使用)