Строки:
q->tail->next=NULL;
free((void *) p);
... должны быть, вероятно,
free( free( (void *) p->next );
p->next=NULL;
, потому что вы не пытаетесь освободить 'p' (это ваш новый 'хвост'), но элемент p-> рядом с которым ты был старым хвостом.Установите указатель на нуль после того, как вы его освободите.Значение q-> tail уже указывает на «p», и после этого нельзя освобождать «p», поскольку «p-> next» - это то, что вы пытаетесь удалить.
Этоможет быть и так.
Кроме того, мне лично не нравится, как вы определили 'Item' как пустоту * где-то, это выглядит странно, потому что 'Item' выглядит как переменная, передаваемая по значениюв стеке.
Кев