【问题标题】:linked list head pointer changing when passed to function c++ [closed]传递给函数c ++时链表头指针发生变化[关闭]
【发布时间】:2012-10-10 13:06:28
【问题描述】:

我在第二年的编程课上遇到了一个问题,涉及创建一组双向链接列表来代表医院以及医院中的医生和患者。医院有医生名单,每个医生都有病人名单。我的问题是,当我调用“hireDoctor”函数将医生添加到医院列表时,不知何故,头指针正在改变。这是我的代码:

    /* adds a Doctor to the Hospital's list of Doctors */
    void Hospital::hireDoctor(Doctor *doc)
    {
        DoctorNode node;
        node.value = *doc;
        DoctorNode* curr;

        if (drListHead == NULL) {    //if doctor list is empty,
            drListHead = &node;    //insert the node at the beginning
            node.next = NULL;
            node.prev = NULL;
        } else {
            curr = drListHead;
            //traverse list until equal or greater (alphabetical) value is found:
            while (curr->value.getLast().compare(node.value.getLast()) < 0 &&
            curr->value.getFirst().compare(node.value.getFirst()) < 0) {
                curr = curr->next;
            }
            if (curr->prev == NULL) {     //if inserting at the beginning of the list
               drListHead = &node;
               node.prev = NULL;
               node.next = curr;
            } else if (curr->next == NULL) { //if the end of the list has been reached
                curr->next = &node;
                node.prev = curr;
                node.next = NULL;
            } else {              //insert the new DoctorNode in the middle:
                curr->next->prev = &node;
                node.next = curr->next;
                curr->next = &node;
                node.prev = curr;
            }
     }

列表中的每个节点都定义为一个结构:

    struct DoctorNode {
      Doctor value;
      DoctorNode *next;
      DoctorNode *prev;
    }

因此,一旦使用了hireDoctor 函数,如果我“雇用”了一位名叫John Smith 的医生,我希望drListHead 指向John Smith,这似乎就是发生的情况。然而,在第二次通过该函数,雇用 Jane Doe 时,drListHead 似乎在进入该函数时已经指向 Jane Doe。我无法弄清楚它在哪里发生了变化。任何想法将不胜感激!

【问题讨论】:

  • 如果您在任何其他文档之后雇用 Doc Zygmunt Zyzz,您的 while 循环取消引用 NULL
  • drListHead 是在哪里定义的?您的问题很可能不在显示的代码中,因为您在调用drListHead 时说已经设置...所以请显示Hospital 的声明和对hireDoctor 的调用 - 我也强烈建议实施在名为 DoublyLinkedList 或类似的类中的双向链表,而不是在名为 Hospital 的类中!
  • 你的 curr-&gt;value.getLast() 应该是 (curr-&gt;value).getLast()
  • 同意如果在你热这个函数之前你的头指针被改变了,那可能是因为其他一些函数运行不好并且改变它 - 你在这里发布的代码似乎对我有用。

标签: c++ pointers linked-list


【解决方案1】:

问题来了:

        if (drListHead == NULL) {    //if doctor list is empty,
            drListHead = &node;    //insert the node at the beginning  <------
            node.next = NULL;
            node.prev = NULL;
        } 

您的节点在堆栈上初始化,退出hireDoctor 后它将指向堆栈的地址。下次您调用hireDoctor 时,节点再次指向同一地址,即 Jane Doe(这只是巧合)。你需要这个:

            if (drListHead == NULL) {    //if doctor list is empty,
                drListHead = new DoctorNode();    //heap allocation 
                drListHead->next = NULL;
                drListHead->prev = NULL;
            }

但请记住,您必须将未使用的内存释放到内存中。

【讨论】:

  • 谢谢!!这解决了我的问题,感谢您的明确解释。
【解决方案2】:

问题出在: DoctorNode node; 这样你的节点就可以在函数中看到;当函数结束时,这个变量被销毁。 因为被破坏的变量是可重用的 ram,但在此 ram 未被其他东西使用之前不会更改,因此您认为仍然具有正确的值。 下一个医生创建要求一些 ram,并且“随便”与以前的医生相同的 ram 是免费的并用于新医生。这意味着您已经重写了头部指向的 ram,也丢失了老医生的所有数据(好吧,数据仍然在这里,只是您没有更多指向它的指针,所以它在某个地方丢失了RAM;这在技术上称为“垃圾”)。

寻找“可变可见性”以获得更好的解释

解决办法是改成指针

DoctorNode node*;

使用“new”来保留 ram,直到您通过调用“delete”明确释放该 ram。如果您在没有释放使用“删除”分配的所有指针的情况下销毁了医生,那么您也在创建垃圾。 见http://www.codeproject.com/Articles/6555/To-new-is-C-To-malloc-is-C-To-mix-them-is-sin

一个常见的问题是用垃圾填充 RAM,这会导致程序甚至操作系统崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 2013-06-25
    • 1970-01-01
    • 2013-05-07
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多