Функции со связным списком, где хранятся указатели

нужно реализовать набор функций для работы со связным списком, в котором всегда хранятся указатели. Список должен быть двусвязный со вспомогательным узлом. В узлах списка требуется хранить указатели на следующий или предыдущей узлы (уже не индексы, как можно было в предыдущих задачах). Каждый узел списка должен быть размещён в динамической памяти, выделенной с помощью malloc. Нужно реализовать следующие функции:

typedef struct Node_s {
struct Node_s * prev , * next ;
void * value ;
} Node ;
//List –- вспомогательный узел, являющийся головой списка
typedef Node List ;
//инициализирует поля структуры *list значениями для пустого списка
void initList ( List * list );
//создаёт новый узел со значением ptr и вставляет его после узла node
//возвращает указатель на созданный узел
Node * addAfter ( Node * node , void * ptr );
//создаёт новый узел со значением ptr и вставляет его перед узлом node
//возвращает указатель на созданный узел
Node * addBefore ( Node * node , void * ptr );
//удаляет заданный узел, возвращая значение, которое в нём лежало
void * erase ( Node * node );

Эти функции должны выделять/удалять память для узлов списка Node, но не для значений: вызывающий полностью контролирует то, куда указывают значения и как для них используется память. входные данные: В первой строке файла записано одно целое число ? — количество тестов в файле. Далее в файле идут тесты (? штук) подряд, один за другим. Первая строка теста начинается с целого числа ? — количество операций, которые нужно выполнить (0 <= ? <= 10^5)полагается, что в начале теста список пустой.Затем идут ? строк, которые описывают операции над списком. В каждой строке сначала записан тип операции: 1 — добавление спереди, -1 — добавление сзади, 0 — удаление. Затем указан индекс узла. Если описывается операция вставки, то в конце также задано целочисленное значение нового узла. Узлам присваиваются индексы в порядке их создания. Самый первый созданный узел имеет индекс 0, следующая операция создания имеет индекс 1, и так далее. Индекс узла никогда не переиспользуется, даже после того, как узел удаляют из списка. Все значения узлов лежат в диапазоне от 0 до 10^6 включительно. Сумма ? по всем тестах не превышает 10^5. **выходные данные:**Для каждого теста нужно вывести значения всех узлов списка после выполнения операций (в порядке их следования в списке), и строку "===" в конце. подскажите пожалуйста, что не так в моем коде, что можно подкорректировать или вставить:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct Node_s {
    struct Node_s *prev, *next;
    void *value;
} Node;
typedef Node List;


Node *first, *last;


Node *addAfter(Node *node, void *ptr) {
    Node *nn = malloc(sizeof(Node));
    nn->value = ptr;
     
    if (node == 0) {
        nn->next = first;
        nn->prev = 0;
        if (first)
            first->prev = nn;   
        first = nn;
    }
    else {
        //(тут наверняка ещё баг)
        nn->prev = node;
        nn->next = node->next;
        node->next = nn;
    }
    return nn;
}

Node *addBefore(Node *node, void *ptr) {
     
    Node *nn = malloc(sizeof(Node));
    nn->value = ptr;
    nn->prev = first;
    nn->next = 0;
    first->next = nn;
    return nn;
}

void *erase(Node *node) {
    
    if (node->next)
        node->next->prev = node->prev;
    if (node->prev)
        node->prev->next = node->next;
     
    node->prev = node->next = (Node*)0xFFFFFFFF;
    return node->value;
}

 
Node *idToNodeXXX[100010] = {0};
Node* *idToNode = idToNodeXXX + 1;    //указывает на 1-ый элемент
int idCnt;
//теперь idToNode[id] --- как бы массив от -1 до 100009 

//отладочный вывод
void dp() {
    //печатаем ВСЕ узлы (даже удалённые) в том виде, в котором нам удобнее проверять правильность
  
    printf("F:%p L:%p\n", first, last);
    for (int id = 0; id < idCnt; id++) {
        Node *node = idToNode[id];
        printf("%p:: V:%d  |  %p %p\n", node, *(int*)node->value, node->prev, node->next);
    }
    printf("----------\n");
 
    fflush(stdout);  
}

int main() {
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

    int tests;
    scanf("%d", &tests);
    dp();

    for (int tn = 0; tn < tests; tn++) {
        int q;
        scanf("%d", &q);

        for (int i = 0; i < q; i++) {
            int type, id;
            scanf("%d%d", &type, &id);

            if (type == 1) {
                //случай id == -1 работает нормально  
                Node *node = idToNode[id];
                int *valueBuff = malloc(sizeof(int));
                scanf("%d", valueBuff);
                Node *nn = addAfter(node, valueBuff);
                idToNode[idCnt++] = nn;
            }
            
            if (type == -1) {
                Node *node = idToNode[id];
                int *valueBuff = malloc(sizeof(int));
                scanf("%d", valueBuff);
                Node *nn = addBefore(node, valueBuff);
                idToNode[idCnt++] = nn;
            }
            if (type == 0) {
                Node *node = idToNode[id];
                void *ptr = erase(node);
            }

             
            dp();
        }

        //печатаем от first до нулевого указателя
        for (Node *ptr = first; ptr; ptr = ptr->next)
            printf("%d\n", *(int*)ptr->value);
        

        printf("===\n");
    }

    return 0;
}

Ответы (0 шт):