删除第一个数字时出现分段错误

Segmentation fault when the first number is deleted

问题是当我删除列表的第一个数字时,我可以删除任何人,但是如果我删除第一个,就会出现分段错误。我是否错误地编写了插入或删除函数(或两者)?

int insert_values(list *l, int value){
  node *new_node = (node*)malloc(sizeof(node));
  if(!new_node) return 1; /*verify if the node was created*/
  new_node->key = value;
  new_node->next = l->head;
  l->head = new_node;
  return 0;
}

void del(list *l, int value){
  node *p = l->head, *q;
  while(p != NULL && p->key != value){
    q = p;
    p = p->next;
  }
  q->next = p->next;
  free(p);
}

当您删除第一个节点时,您需要将head更改为指向它之后的节点。否则,您将继续尝试使用已释放的节点。

void del(list *l, int value){
  node *p = l->head, *q;
  while(p != NULL && p->key != value){
    q = p;
    p = p->next;
  }
  q->next = p->next;
  if (p == l->head) {
    // Change head to point to next node
    l->head = p->next;
  }
  free(p);
}

如果在遍历列表以查找要删除的节点时保持指向当前节点的指针到指针,则不必担心任何特殊比如是否删除头节点。例如:

/** delete node with value v from list (for loop) */
void del_node (list *l, int v)
{
    node **ppn = &l->head;      /* pointer to pointer */
    node *pn = l->head;         /* pointer to node */

    for (; pn; ppn = &pn->next, pn = pn->next) {
        if (pn->data == v) {
            *ppn = pn->next;    /* set address to next */
            free (pn);
            break;
        }
    }
}

这消除了特殊情况,因为 ppn 保存了 要删除的节点的 地址。为节点地址分配一个新指针不会更改节点地址,只会更改其内容,从而无需检查该节点是否是您的第一个节点。在 Linus on understanding pointers

中有更全面的解释

假设您使用的设置如下:

typedef struct node {       /* list node */
    int data;
    struct node *next;
} node;

typedef struct {            /* list wrapper with head & tail pointers */
    node *head, *tail;
} list;

(从你的问题可以看出你是)