【问题标题】:member access within null pointer of type 'struct ListNode'“struct ListNode”类型的空指针内的成员访问
【发布时间】:2017-11-27 18:39:11
【问题描述】:
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == NULL) return false;
        ListNode* walker = head;
        ListNode* runner = head;
        while(runner->next != NULL && walker->next != NULL){
            walker = walker->next;
            runner = runner->next->next;
            if(walker == runner) return true;
        }
        return false;
    }
};

我正在练习一个看起来很简单的面试代码。我必须返回一个确定单链表是否有循环的布尔值。我做了两个指针 walker 移动 1 步和 runner 每次迭代移动 2 步。

然后这段代码给了我一个错误:

Line 15: member access within null pointer of type 'struct ListNode'

是什么导致了这个错误?

【问题讨论】:

  • 是否有一些静态代码分析工具在该代码上运行?
  • 每次迭代移动两步很危险,不是吗?你怎么知道列表有偶数个元素?
  • 我建议你学习使用调试器。
  • 看来您需要rubber_duck...

标签: c++ data-structures linked-list


【解决方案1】:

您只需确保runner->next 不为空,但在分配之后

runner = runner->next->next;

runner 可以为空。

【讨论】:

  • walker 相同。
  • @juanchopanza walker 不一样,它被分配了walker->next 被检查为空。
【解决方案2】:

这应该可以解决它:

bool hasCycle(ListNode *head) {
    if(head == NULL || head->next == NULL) { return false; }
    struct ListNode * walker = new ListNode(1);
    struct ListNode * runner = new ListNode(2);
    walker = head;
    runner = walker->next;
    while(walker != fast){
        if(runner == NULL || runner->next == NULL) { return false; }
        walker = walker->next;
        runner = runner->next->next;
    }
    return true;
}

【讨论】:

    【解决方案3】:

    //- 如果从圆形路径开始循环,那么他们有 100% 的机会会在某个时间点相遇,所以这里我们选择一个走一步的步行者和一个走两步的跑步者。

    bool hasCycle(ListNode *head){
    if(head == NULL || head->next == NULL)
           return false; 
    
    struct ListNode *temp  = head; 
    struct ListNode *walker; 
    struct ListNode *runner;
    walker = runner= head;
    while(temp ){
      walker = walker->next;
      runner = runner->next->next;
        if(runner == walker) // as soon both get at same address we got return as 
         true value.
         { return True; }
        temp = temp->next;
    }
    return false;
    

    }

    【讨论】:

    • 你也应该解释一下。
    【解决方案4】:

    下面的代码应该可以正常工作。
    这是经典的Hare-Tortoise定理,兔子走2步(距离单位),而乌龟走1。

    我认为您没有检查导致此错误的 runner->next->next 的无效性

    bool hasCycle(ListNode *head) 
    {
        if(head == NULL || head->next == NULL) 
        { 
           return false;
        }
        ListNode* tortoise=new ListNode();
        ListNode* hare = new ListNode();
        tortoise=head;
        hare=tortoise->next;
        while(tortoise != hare)
        {
            if(hare == NULL || hare->next == NULL) 
            { 
               return false; 
            }
            tortoise=tortoise->next;
            hare=hare->next->next;
        }
        return true;
    }
    

    【讨论】:

      【解决方案5】:

      排序答案在这里有解释

      它返回错误,因为runner=runner->next->next 可以为 NULL 并且您在调节时检查 runner->next!=NULL ,所以您 必须在你的代码中做一点改变才能得到你的答案 while 条件检查 runner->next->next!=NULL 并获得正确的 回答。

      快乐编码 :>)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-02
        • 2022-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-19
        • 1970-01-01
        相关资源
        最近更新 更多