【问题标题】:How to resolve the corrupted pointer in the linked list?如何解决链表中损坏的指针?
【发布时间】:2012-06-24 01:27:09
【问题描述】:

如果我发现链表中的指针(链接)字段已损坏,我该如何解决这个问题?

我在面试中被问到这个问题。我说不行,解决不了。面试官说有可能。有什么办法吗?

【问题讨论】:

  • 你是怎么知道的? 如果你发现,你会有比你的程序逻辑更好的逻辑,当你有更好的逻辑时,为什么不首先使用它。 (这是变相的哥德尔合取)
  • 确实你是怎么发现的?一般情况下是不可能的……
  • 请参考以下链接中如何找出损坏指针的答案:stackoverflow.com/questions/4079099/…
  • @thrustmaster:我一直在为我的问题发布的所有答案在逻辑上正确的答案投票。
  • 不请自来的一般面试相关建议...不要做出无根据的假设,导致您给出的答案不令人满意。询问详细信息(单链接、双链接、我们如何知道它已损坏、解析意味着什么、是否可以读取任意地址的内存而不会导致崩溃等)。如果他们没有给你任何细节,考虑不同的情况,如果这个和那个是这样那样,描述这些情况以及在它们中可以做什么。

标签: c linked-list


【解决方案1】:

假设它是一个双向链表:

如果损坏的是“下一个”指针,则可以从尾部开始并使用“上一个”指针,向头部遍历列表,同时保持对已遍历的最后一个元素的引用。当您找到具有错误指针的元素时,您只需将该元素的“下一个”指针指向被遍历的最后一个元素。

如果双向链表中的“上一个”链接损坏,则可以反转该过程 - 从头部开始,遍历直到找到错误的“上一个”指针,并使用对最后一个元素的引用来修复它遍历。

【讨论】:

    【解决方案2】:

    在开发我的嵌入式作业时,我经常使用前向链接队列。我记数以及头指针。队列有一个 check() 方法,该方法运行 [count] 个链接,如果结果指针与头部不同,则调用关键错误处理程序。它不是万无一失的,但它可以很好地捕获双推和其他此类常见的队列错误。

    注意:在多线程应用程序中,队列必须被锁定才能安全检查。

    【讨论】:

      【解决方案3】:

      在双向循环链表中,如果指针(前一个或下一个指针)中的任何一个被损坏,我们可以解析损坏的指针。

      如果next指针不正确,我们可以反向遍历链表,然后纠正它,否则如果前一个指针不正确,我们可以向前遍历链表纠正它。

      现在我们必须考虑如何识别列表中损坏的链接(指针)。我们使用分别为每个节点分配动态内存(malloccalloc)。如果我们频繁调用malloccalloc,因为内存很小,可能会影响系统的性能。而不是这样,我们可以在初始阶段分配一大堆堆内存,然后我们可以为每个节点创建实现自己的内存分配功能。并且也仅将其用于创建列表节点以识别列表的损坏链接。

      这提高了系统的性能,还有助于通过检查分配给列表的初始内存的限制来识别节点的链接是否损坏。

      一旦我们得到一个指向节点的指针,我们必须在访问该节点中的数据之前首先进行以​​下检查。

      check_limit(node);
      check_limit(node->next);
      check_limit(node->previous);
      

      我们还可以检查node->previous 是否等于current_node

      在此之后,node->next 也可能指向错误的地址,但在初始内存限制内。在这种情况下,我们可以读取node->next->previous(这不会导致崩溃,即使next 指向错误的地址但在初始内存限制内)并检查它是否等于node

      而且未使用的初始内存空间也应始终设置为NULL(使用memset)。

      通过这些方法,我们可以找出列表中 99% 的损坏指针。

      【讨论】:

      • 我看不到逻辑。如果(one->next == two && two->prev != one),你怎么知道[a] 你是否必须设置two->prev = one; 或[b] one->next 首先是错误的?没有办法说。 (有更简单的情况,例如 if (two->prev == three && three->next == two),这表明在第一种情况下 one->next 是错误的)
      【解决方案4】:

      在双向循环链表中,如果损坏的指针指向节点的内存位置之一,则首先使用遍历和标记方法找到循环。这将给出具有损坏指针的节点的位置,然后以相反的顺序遍历,然后找出具有上一个节点位置的节点作为第一步结果节点。在该节点旁边分配损坏节点的指针。问题已解决 在反之亦然场景中逆时针反转。 上面的解决方案需要o(N)个空间来匹配遍历的节点地址。

      【讨论】:

        【解决方案5】:

        也许你应该摆脱它? 确实,在一般情况下这是不可能的,因为我们不能只插入其他列表中的任何元素。

        【讨论】:

        • 作为评论可能会更好:)
        猜你喜欢
        • 2017-12-14
        • 1970-01-01
        • 2019-03-17
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多