I am trying to build and test a linked list in C. But I can't seem to figure out why I am getting segmentation fault from running the test (test_linked_list.c). The problem seems to be from the list_delete function when running gdb, but I can't find where the problem is. Why is this wrong?
linkedlist.c:
#include <stdio.h>
#include <string.h>
#include "linked_list.h"
void list_init(list_t *h) {
    *h = NULL;
}
int list_size(const list_t *h) {
    node_t *p = *h;
    int r = 0;
    do {
        r += 1;
        p = p->next;
    } while (p);
    return r;
}
int list_empty(const list_t *h) {
    return (*h == NULL);
}
void list_insert(list_t *h, node_t *n) {
    n->next = *h;
    *h = n;
}
node_t *list_find(const list_t *h, int id) {
    node_t *p = *h;
    while (p) {
        if (p->id == id)
            return p;
        p = p->next;
    }
}
node_t *list_find_before(const list_t *h, int id) {
    node_t *p = *h;
    while (p && p->next) {
        if (p->next->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}
node_t *list_delete(list_t *h, int id) {
    node_t *r = NULL;
    if (*h && (*h)->id == id) {
        r = *h;
        *h = NULL;
        return r;
    }
    // Here we have a syntax bug
    node_t *p = list_find_before(h, id);
    if (p) {
        r = p->next;
        p->next = p->next->next;
        r->next = NULL; 
    }
    return r;
}
void print_list(const list_t *h) {
    node_t *p = *h;
    while (p) {
        printf("%d: %s says %s\n", p->id, p->name, p->msg);
        p = p->next;
    }
}
test_linked_list.c:
#include <stdlib.h>
#include "linked_list.h"
#include <string.h>
#include <assert.h>
#include <stdio.h>
void test_delete_one() {
    list_t h;
    list_init(&h);
    node_t n;
    n.id = 0;
    strcpy(n.name, "hello");
    strcpy(n.msg, "world");
    list_insert(&h, &n);
    node_t *f = list_delete(&h, 0);
    assert(f == &n);
}
void test_delete() {
    list_t h;
    list_init(&h);
    node_t n[3];
    int i;
    for (i = 0; i < 3; i++) {
        n[i].id = i;
        list_insert(&h, &n[i]);
    }
    list_delete(&h, 1);
    assert(list_size(&h) == 2);
}
void core_dump_test() {
    int size = 0;
    list_t h;
    list_init(&h);
    size = list_size(&h);   
    printf("list size is: %d\n", size);
}
int main() {
    test_delete();
    test_delete_one();
    core_dump_test();
    printf("Pass\n");
}
 
     
    