指针、静态对象和新对象
Pointers and static and new objects
首先,如果这是一个重复的问题,请道歉。我只是在学习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作为所有权(这有点高级,但要尽早使用)
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- C++ 如何在将新对象分配给另一个对象时创建新对象
- 重用对象与创建新对象
- C++,创建新对象时类的对象更改
- 运算符重载 += 添加新对象
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 从使用概念定义的函数返回新对象
- 从 Rcpp 函数返回指向"新"对象的指针的正确方法
- 如何删除派生类中基类对象的新对象
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 为模板参数类型中的新对象分配内存
- 删除通过取消引用新对象初始化的对象
- C++ 实例化新对象时不接受继承方法默认参数值
- 有没有办法删除传递给函数"foo(新对象())"的对象?
- 将 Eigen::MatrixXd 转换为 arma::mat 并在新对象上制作副本
- 创建新对象并立即为其设置属性时出现编译器错误
- 如何异步销毁对象并立即分配一个新对象
- 删除传递给 C++ 中成员函数的新对象
- 具有构造函数的新对象数组,需要在C++中设置参数
- 我可以制作一个对象方法,如果单独调用,它将自行修改,但如果在复制初始化期间调用,则会返回一个新对象?