удаление последнего элемента из связанного списка - PullRequest
0 голосов
/ 30 апреля 2019

Для проекта мне нужна реализация связанного списка в C, которая позволяет мне удалить последний элемент.

Однако я не знаю, как этого добиться. Идея состояла в том, чтобы создать функцию (deleteLast), которая выполняет итерации по списку до тех пор, пока следующий из следующего элемента не станет равным NULL (так, пока не будет достигнут второй последний элемент), чтобы затем освободить ссылку на последний элемент.

Тем не менее, я получаю сообщение об ошибке "выражение должно иметь указатель на тип структуры или объединения" при попытке компиляции.

#include <stdio.h>
#include <stdlib.h>

struct cell{
    int x_coord,y_coord;
    struct cell *next;
} cell;

struct cell AddToList (struct cell *list, int x,int y);
int listlength(struct cell * list);
void deleteLast(struct cell **list);

struct cell AddToList(struct cell *list,int x,int y){
    struct cell *new_cell;
    new_cell = malloc(sizeof(struct cell));
    new_cell->x_coord=x;
    new_cell->y_coord=y;
    printf("Added new coordinates %i %i",x,y);
}

int listlength(struct cell *list){
    int i=0;
    while(list->next != NULL){
        i++;
    }
    return i;
}

//takes a pointer as reference, because in C parameters are given as values
//see: https://stackoverflow.com/a/35021864
//calls should look like deleteLast( &list )
void deleteLast(struct cell **list){
    struct cell *currentcell = *list;
    while(*list->next->next != NULL){ //expression must have pointer-to-struct-or-union type
        //free list->next
    }
}

Где ошибка?

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

С тех пор, как Даниэль Сигел прямо попросил меня расширить ответ Эндрю Сен-Пьера.Вот что я написал в комментариях.

Вы всегда должны проверять, является ли ваш указатель не NULL, прежде чем разыменовывать его, и вы должны назначить NULL явным образом после освобождения чего-либо, потому что free не сделает этого за вас, нооставлю вам указатель, который выглядит хорошо, но ни на что не указывает.

void deleteLast(struct cell **list){
    //Do nothing if list is a NULL
    if (!list){
        return;
    }
    struct cell * currentcell = *list;
    //Do nothing if list is empty
    if (!currentcell){
        return;
    }
    //Check if first element is last element
    if (!currentcell->next){
        free(currentcell);
        //assign NULL to the pointer in list not to currentcell
        //since currentcell is a local variable.
        *list = NULL;
        return;
    }
    while(currentcell->next->next != NULL) {
        currentcell = currentcell->next;
    }
    free(currentcell->next);
    //explicit set last element to NULL
    currentcell->next = NULL;
}
1 голос
/ 30 апреля 2019
void deleteLast(struct cell **list){
    struct cell * currentcell = *list;
    while(currentcell->next->next != NULL) {
        currentcell = currentcell->next;
    }
    free(currentcell->next);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...