【问题标题】:C++ Pointer node [closed]C++指针节点[关闭]
【发布时间】:2017-05-29 06:14:20
【问题描述】:

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

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;
}

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

【问题讨论】:

  • 什么是“奇怪的错误”?
  • 输出指针链表中的值时,无限输出链表中的最后一个值

标签: c++


【解决方案1】:

您正在将节点设置为指向本地堆栈变量,当您进入 for 循环的下一次迭代时,该变量将被销毁。

您对new Student 的使用通过进行堆分配解决了这个问题

Stack Memory vs Heap Memory 有很多关于堆内存与栈内存的很好讨论

【讨论】:

    【解决方案2】:

    当你这样声明一个学生时

    Student next(0);

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

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

    new Student(0);
    

    【讨论】:

      【解决方案3】:

      通过做

      Student next(0);
      

      您正在分配堆栈上的对象。

      new Student(0);
      

      您在堆中分配对象。

      一旦您离开作用域,您将访问不再属于您的内存并且可以被其他函数覆盖。

      【讨论】:

      • 我只想评论正在擦除的堆栈。对象超出范围时不会删除数据。它只是供其他内存使用以覆盖它。它可能存在也可能不存在,有点像薛定谔的数据。
      • 没有。这不是真的。事实是,您无法知道对象超出范围后会发生什么。它可能徘徊,它可能被释放并被零或垃圾覆盖 - 你只是不知道。您所做 知道的是,如果您在其生命周期结束后尝试访问它会发生什么情况,那么您根本不应该这样做。 实际会发生什么完全取决于您的平台和编译器。
      • 我同意我的描述不准确......所以我编辑了我的答案。
      • @DoronYakovlev-Golani:仍然不正确。 可能会发生访问不再属于您且可以被其他函数覆盖的内存。你的回答听起来像是肯定的。甚至可能根本没有任何内存访问。
      • @Christian-Hackl,我认为我目前的回答反映了您提到的内容。一旦超出范围,该内存就不属于您(即使您保留指向它的指针)。这是肯定的。如果您不访问它,则不会发生任何错误,但这不是问题。但是,访问它肯定是错误的(即使在某些情况下,您可能不会遇到问题行为)。
      【解决方案4】:
      for(int i=0;i<3;i++){
         pointer->val = i;
         Student next(0);
         pointer->next = &next;
         pointer = pointer->next;
      }
      

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

      pointer-&gt;next = new Student(0);

      在动态存储上创建(通常实现为堆)。这个对象会一直存在,直到你告诉它死亡(删除它)。

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

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

      【讨论】:

      • 阅读 C++ 中“堆栈”和“堆”之间的区别还应该包含解释这两个词如何含糊和/或不正确的材料。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 2021-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      相关资源
      最近更新 更多