每当我们创建新节点时,首先将指针指向新节点并动态分配内存是管理的吗?为什么我们不能有节点类的普通变量!那么,节点类型的普通变量代替指针指向节点类型有什么问题
代码:
//creation of linked list
#include <iostream>
using namespace std;
class node{
public:
int data;
node* next;
};
class linked_list{
public:
node* head;
linked_list(){
head=NULL;
}
void add_node(int data);
void display_ll();
};
void linked_list :: add_node(int data){
node newnode; //HERE IN THIS LINE I KNOW IT SHOULD BE LIKE node* newnode;
if (head==NULL){ // AND DMA THAT NODE , WORKING FINE BUT WHAT'S WRONG WITH ACTUAL CODE
newnode.data=data;
newnode.next=NULL;
head=&newnode;
}
else{
node* temp=head;
newnode.data=data;
newnode.next=NULL;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=&newnode;
}
}
void linked_list :: display_ll(){
node* temp=head;
while (temp!=NULL)
{
cout<<temp->data<<" ";
temp=temp->next;
}
}
int main(){
linked_list ll;
ll.add_node(6);
ll.add_node(3);
ll.add_node(9);
ll.add_node(3);
ll.display_ll();
}
如果在方法中将newnode
声明为node newnode;
,那么对象的内存将在堆栈上分配,其生存时间是方法执行上下文的本地时间:当函数返回时,该内存将被释放。
这就成了一个问题,因为在第一次调用(ll.add_node(6)
(之后,head
将引用释放的内存。然后ll.add_node(3)
将再次分配内存,这很可能是堆栈上相同的内存,因此您实际上会覆盖第一个节点的数据,而temp->next=&newnode
将做出错误的引用。其他ll.add_node
调用也会发生这种情况。因此,该列表已损坏。
当您最终调用ll.display_ll()
时,它的temp
将指向释放的内存,temp->next
也将指向,从而导致未定义的行为、意外输出,并可能导致异常。
因此,规则如下:
如果您的函数创建了一个对对象的引用,该对象在函数返回后将保持可访问性,那么您必须动态分配内存(使用指针(。另一方面,如果对象仅在函数执行期间相关,并且可以在函数返回时丢弃(不引用它(,则不需要使用指针。