You're not modifying the caller's pointer when requesting the very node it points to as the delete request. The following, a cut down version of some of your code, demonstrates one way to do this:
#include <stdio.h>
#include <stdlib.h>
typedef struct record rec;
struct record
{
int data;
rec *prev, *next;
};
void delete_node (rec ** pp, int num)
{
if (!*pp)
return;
// find the num'th node
while (num-- && *pp)
pp = &(*pp)->next;
// setup victim
rec *victim = *pp;
// non-self-reference node means just rewire
if (victim && (victim != victim->next))
{
victim->prev->next = victim->next;
victim->next->prev = victim->prev;
*pp = victim->next;
}
else
{ // deleted node was self-referenced. last node
*pp = NULL;
}
free(victim);
}
void iterfwd(const rec* list)
{
const rec *p = list;
printf("list: %p\n", list);
if (p)
{
for (; p; p = (p->next != list ? p->next : NULL))
printf("prev: %p, self:%p, next:%p, data = %d\n", p->prev, p, p->next, p->data);
}
puts("");
}
void insert(rec **pp, int data)
{
// setup new node
rec *newp = malloc(sizeof(*newp));
newp->data = data;
if (!*pp)
{
newp->next = newp->prev = newp;
*pp = newp;
}
else
{ // insert between prev and head.
newp->next = *pp;
(*pp)->prev->next = newp;
newp->prev = (*pp)->prev;
(*pp)->prev = newp;
}
}
int main()
{
rec *list = NULL;
int i;
for (i=1; i<=5; ++i)
insert(&list, i);
iterfwd(list);
// delete fourth node (0-based)
delete_node(&list, 3);
iterfwd(list);
// delete first node (0-based)
delete_node(&list, 0);
iterfwd(list);
// delete first node (0-based)
delete_node(&list, 0);
iterfwd(list);
// delete first node (0-based)
delete_node(&list, 0);
iterfwd(list);
// delete first node (0-based)
delete_node(&list, 0);
iterfwd(list);
return 0;
}
Output (obviously system dependent)
Note how the passed-in pointer (pass by address) is modified when requesting the 0-element is removed.
list: 0x100103af0
prev: 0x100103b70, self:0x100103af0, next:0x100103b10, data = 1
prev: 0x100103af0, self:0x100103b10, next:0x100103b30, data = 2
prev: 0x100103b10, self:0x100103b30, next:0x100103b50, data = 3
prev: 0x100103b30, self:0x100103b50, next:0x100103b70, data = 4
prev: 0x100103b50, self:0x100103b70, next:0x100103af0, data = 5
list: 0x100103af0
prev: 0x100103b70, self:0x100103af0, next:0x100103b10, data = 1
prev: 0x100103af0, self:0x100103b10, next:0x100103b30, data = 2
prev: 0x100103b10, self:0x100103b30, next:0x100103b70, data = 3
prev: 0x100103b30, self:0x100103b70, next:0x100103af0, data = 5
list: 0x100103b10
prev: 0x100103b70, self:0x100103b10, next:0x100103b30, data = 2
prev: 0x100103b10, self:0x100103b30, next:0x100103b70, data = 3
prev: 0x100103b30, self:0x100103b70, next:0x100103b10, data = 5
list: 0x100103b30
prev: 0x100103b70, self:0x100103b30, next:0x100103b70, data = 3
prev: 0x100103b30, self:0x100103b70, next:0x100103b30, data = 5
list: 0x100103b70
prev: 0x100103b70, self:0x100103b70, next:0x100103b70, data = 5
list: 0x0