【问题标题】:This code works on Xcode but fails in leetcode compiler此代码适用于 Xcode,但在 leetcode 编译器中失败
【发布时间】:2019-04-04 04:55:54
【问题描述】:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* removeElements(struct ListNode* head, int val) {

    struct ListNode *beforeNode = head;

    while(beforeNode != NULL){

        if(head == beforeNode && head->val == val){
            struct ListNode* q = head;
            head = q->next;
            beforeNode = head;
            free(q);
        }
        else if(beforeNode->next != NULL && beforeNode->next->val == val){
            struct ListNode *p = beforeNode->next;
            beforeNode = p->next;
            free(p);
        }

       else
           beforeNode = beforeNode->next;

    }

    return head;
}

【问题讨论】:

  • 我看不出这段代码有什么问题
  • 你得到什么错误?
  • 你能提供一段完整的可编译代码吗?
  • 不,我没有遇到问题,但 leetcode 编译器说您使用了已释放的内存,但我不这么认为。这可能是他们的问题
  • @bake 为了理解这一点,我们需要足够的代码来复制问题。

标签: c


【解决方案1】:

此代码在 Xcode 上工作,但在 leetcode 编译器中失败

好吧,代码在任何平台上都不起作用

您在 Xcode 上所做的测试一定是不完整的,因为代码在任何平台上都有未定义的行为。

看这个简单的例子:

#include <stdio.h>
#include <stdlib.h>

struct ListNode
{
  struct ListNode *next;
  int val;
};

void printList(struct ListNode* p)
{
  if (p)
  {
    printf("%p %d", (void*)p, p->val);
    while(p->next)
    {
      printf("->");
      p = p->next;
      printf("%p %d", (void*)p, p->val);
    }
  }
  printf("\n");
}


// Function from question
struct ListNode* removeElements(struct ListNode* head, int val) {

    struct ListNode *beforeNode = head;

    while(beforeNode != NULL){

        if(head == beforeNode && head->val == val){
            struct ListNode* q = head;
            head = q->next;
            beforeNode = head;
            free(q);
        }
        else if(beforeNode->next != NULL && beforeNode->next->val == val){
            struct ListNode *p = beforeNode->next;
            beforeNode = p->next;
            printf("Free val %p %d\n", (void*)p, p->val);
            free(p);
        }

       else
           beforeNode = beforeNode->next;

    }

    return head;
}

int main()
{
  // Initialize a list with three element like: 1->42->1->NULL
  struct ListNode *head = malloc(sizeof *head);
  head->val = 1;
  head->next = malloc(sizeof *head);
  head->next->val = 42;
  head->next->next = malloc(sizeof *head);
  head->next->next->val = 1;
  head->next->next->next = NULL;

  printList(head);

  removeElements(head, 42);

  printList(head);

  return 0;
}

示例输出:

0x558311c02260 1->0x558311c02280 42->0x558311c022a0 1
Free val 0x558311c02280 42
0x558311c02260 1->0x558311c02280 42

如您所见,有两个问题:

  • 结果列表为 1->42,但我们预期为 1->1 换句话说 - 列表已损坏。

  • 最后一行打印的节点是我们刚刚释放的节点(即 0x558311c02280)。那是未定义的行为。

问题出在这一行:

beforeNode = p->next;

应该是

beforeNode->next = p->next;

上述更改后的输出:

0x561def3e6260 1->0x561def3e6280 42->0x561def3e62a0 1
Free val 0x561def3e6280 42
0x561def3e6260 1->0x561def3e62a0 1

现在列表是正确的,没有使用释放的内存。

【讨论】:

  • @bake 好吧,在这种情况下你应该删除问题
猜你喜欢
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 2010-12-31
  • 2015-11-04
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多