C++指针节点

C++ Pointer node

本文关键字:节点 指针 C++      更新时间:2023-10-16

当我以这种方式编写下一个代码时,它会返回奇怪的错误。

struct Student{
    int val;
    Student* next;
    Student(int a){
        val = a;
        next = NULL;
    }
};
int main(){
Student begin(0);
Student *head = &begin;
Student *pointer = head;
for(int i=0;i<3;i++){
    pointer->val = i;
    Student next(0);
    pointer->next = &next;
    pointer = pointer->next;
}
while(head != NULL){
    cout<< head-> val<<endl;
    head = head ->next;
}
}

将循环更改为这种方式后,它可以工作。

for(int i=0;i<3;i++){
    pointer->val = i;
    pointer->next = new Student(0);
    pointer = pointer->next;
}

为什么会这样?这两种初始化下一个节点的方法之间有什么区别吗?

您正在将节点设置为指向一个局部堆栈变量,当您转到 for 循环的下一次迭代时,该变量将被销毁。

您对new Student的使用通过进行堆分配来解决此问题

在堆栈内存

与堆内存中有很多关于堆与堆栈内存的良好讨论

当你像这样声明学生时

Student next(0);

它在堆栈上分配临时内存,这些内存应仅被视为在该块中可用。

使用new时,可以在堆上分配可在任何地方使用的内存。注意内存泄漏并始终定义析构函数。

new Student(0);
for(int i=0;i<3;i++){
   pointer->val = i;
   Student next(0);
   pointer->next = &next;
   pointer = pointer->next;
}

您正在自动存储(通常作为堆栈实现)上创建对象学生。 然后,您将指向此对象的指针存储在链表中。 当"学生"超出范围时,对象将被删除。现在你的指针是一个悬空的指针。 取消引用该指针现在是未定义的行为。

pointer->next = new Student(0);

在动态存储(通常作为堆实现)上创建。 此对象将一直存在,直到您告诉它死亡(删除它)。

我建议您阅读有关C++中堆栈/堆之间的差异的信息。 如果你想学习C++,这是一个非常重要的话题。

另外,请确保您删除了任何新对象! 如果不这样做,最终会在程序中出现内存泄漏。

通过做

Student next(0);

您正在堆栈上分配对象。

new Student(0);

您正在堆中分配对象。

离开示波器后,您将访问不再属于您的内存,并且可以被其他功能覆盖。