C++ 指针、静态对象和新对象
首先,如果这是一个重复的问题,请道歉。我只是学习C++,可能不知道正确的搜索词来找到我已经肯定的问题。 不管怎样,我通过在代码上工作30天来教自己C++。然而,当被要求为LinkedList实现C++ 指针、静态对象和新对象,c++,linked-list,C++,Linked List,首先,如果这是一个重复的问题,请道歉。我只是学习C++,可能不知道正确的搜索词来找到我已经肯定的问题。 不管怎样,我通过在代码上工作30天来教自己C++。然而,当被要求为LinkedList实现insert方法时,我遇到了一个似乎无法解决的障碍。从概念上讲,我知道需要做什么,但从语法上讲,我遇到了一个问题 下面是我的代码,包括调试打印输出。似乎正在发生的是,new_节点总是被放在内存中的相同位置,而不管它的迭代是在哪个循环上进行的。我如何确保它在内存中有一个新的位置?无论是否将new\u节点声明
insert
方法时,我遇到了一个似乎无法解决的障碍。从概念上讲,我知道需要做什么,但从语法上讲,我遇到了一个问题
下面是我的代码,包括调试打印输出。似乎正在发生的是,new_节点
总是被放在内存中的相同位置,而不管它的迭代是在哪个循环上进行的。我如何确保它在内存中有一个新的位置?无论是否将new\u节点声明为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);
}
这一直持续到分段错误导致它陷入无限循环
你知道为什么new\u节点
总是被放在同一个内存位置(有或没有static
)吗?这难道不是主要问题,我完全没有抓住重点吗?提前谢谢
——C++新手。< /P>
编辑:这里的建议并没有完全解决这个问题。我的问题不是理解指针和引用之间的区别,而是理解以下两者之间的区别:
Node node_1 = Node(data);
static node_2 = Node(data);
node_3 = new Node(data);
由于我在写问题时不知道新的
操作符(显然!),我不知道(a)搜索这个词或(b)在标题中包含这个词。为了清晰起见,对标题进行了编辑,并将此编辑包括在内,以供将来的读者阅读。当您声明变量静态时,该变量只有一个副本。它是在您第一次执行声明时创建的,以后对该函数的调用将重用相同的数据。因此,每次使用新节点时,它都是同一个节点
您需要使用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*头,int数据)
{
cout当你声明一个变量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*头,int数据)
{
您可以使用静态变量。这些变量只创建一次,并且对于每个函数调用都是相同的!
您的目的是始终创建一个新节点,因此这些变量不是静态的
试一下
Node* new_head = new Node(data);
return new_head;
// as well as
Node* new_node = new Node(data);
curr->next = new_node;
所有节点都必须在空闲存储上创建(使用new),否则在函数结束时会被清除。
这意味着您总是引用不存在的变量,这是内存损坏。您还必须提供析构函数来删除新的节点。
有关更多信息,请阅读变量的寿命
进一步说明:
- 使用空ptr
- std::list或std::linked_list是列表的容器(我知道,你想学习,但看看它们)
- 您的类是all public->您可以使用结构,因为它对于访问说明符是相同的,但默认为public
- 对所有权使用unique_ptr(这有点高级,但要尽早使用)
您使用静态变量。这些变量只创建一次,并且对于每个函数调用都是相同的!
您的目的是始终创建一个新节点,因此这些变量不是静态的
试一下
Node* new_head = new Node(data);
return new_head;
// as well as
Node* new_node = new Node(data);
curr->next = new_node;
所有节点都必须在空闲存储上创建(使用new),否则在函数结束时会被清除。
这意味着您总是引用不存在的变量,这是内存损坏。您还必须提供析构函数来删除新的节点。
有关更多信息,请阅读变量的寿命
进一步说明:
- 使用空ptr
- std::list或std::linked_list是列表的容器(我知道,你想学习,但看看它们)
- 您的类是all public->您可以使用结构,因为它对于访问说明符是相同的,但默认为public
- 对所有权使用unique_ptr(这有点高级,但要尽早使用)
链表是学习编程语言的人被迫学习指针的一种恶习。这里的关键是指针的所有权(指针不再需要时由谁负责维护和释放指向的内存)和指向的内存的寿命(何时删除).关于链表和让链表工作,没有什么能比在一张纸上画出所需的连接和更改,然后使用该图来建立需要执行的操作更好的了。嗯…:-D我衷心地同意你的第一个工具,当你制定出这样的算法时,必须是“一个合法的便笺簿和一支二号铅笔。”#########在我看来,所写的实现似乎有点太巴洛克风格了:你真的不需要一个curr
和一个next
指针。你只需要迭代,直到你发现curr->next==NULL
。在这一点上,你就分配了一个新节点(其next
指针为NULL
),并将其分配给curr->next
。正如您的“法律便笺簿和第二号铅笔”所示。@MikeRobinson感谢您的反馈,但您俩都不是