Witam!
Próbuję napisać program obsługujący listę dwukierunkową. Wszystko szło dobrze, do momentu aż chciałem napisać funkcję usuwającą ostatni element listy. Program wyświetlił błąd: Naruszenie ochrony pamięci. Programowałem wcześniej w C++ lecz niestety projekt muszę napisać w C stąd mogą wystąpić głupie błędy, których po prostu nie widzę.
Byłbym bardzo wdzięczny gdyby ktoś pomógł mi i ewentualnie wytłumaczył co robiłem źle.
Poniżej cały kod (najbardziej aktualny, ale wciąż niedokończony :) )
#include <stdio.h>
#include <stdlib.h>
//-------------- S T R U K T U R A ---------------------
typedef struct ellist{
struct ellist *nast, *popr;
int wartosc;
}elist;
//------------------------------------------------------
//-------------- OBSLUGA LISTY -------------------------
//------------------------------------------------------
void wypisz_liste(elist *lista){
elist *aktu=lista;
while (aktu->popr != NULL){
aktu = aktu->popr;
}
int i=1;
while(aktu != NULL){
printf("%3d. %5d \n",i,aktu->wartosc);
aktu = aktu->nast;
i++;
}
}
////////////////////////////////////////////////////////
void dodaj_kon(elist *lista, int l){
elist *aktu=lista, *nowy;
while (aktu->nast != NULL){
aktu = aktu->nast;
}
nowy = malloc(sizeof (elist));
nowy->wartosc = l;
nowy->nast = NULL;
aktu->nast = nowy;
}
////////////////////////////////////////////////////////
void dodaj_pocz(elist *lista, int l){
elist *aktu=lista, *nowy;
nowy = malloc(sizeof (elist));
while (aktu->popr != NULL){
aktu = aktu->popr;
}
nowy->wartosc = l;
nowy->nast = aktu;
nowy->popr = NULL;
aktu->popr = nowy;
}
////////////////////////////////////////////////////////
void dodaj_srod(elist *lista, int l, int miej){
elist *aktu=lista, *nowy;
int i=1;
nowy = malloc(sizeof (elist));
nowy->wartosc=l;
while (aktu->popr != NULL){
aktu = aktu->popr;
}
while (aktu->nast != NULL) {
if(i == miej){
nowy->nast = aktu;
nowy->popr = aktu->popr;
aktu->popr = nowy;
(nowy->popr)->nast = nowy;
break;
}
i++;
aktu=aktu->nast;
}
}
////////////////////////////////////////////////////////
void usun_pocz(elist *lista){
elist *aktu=lista;
while (aktu->popr != NULL){
aktu = aktu->popr;
}
(aktu->nast)->popr = NULL;
free(aktu);
}
////////////////////////////////////////////////////////
void usun_kon(elist *lista){
elist *aktu=lista;
while (aktu->nast != NULL){
aktu = aktu->nast; // Jesli dobrze rozumiem to:
}// whilem przechodze na koniec listy
(aktu->popr)->nast=NULL; //ustawiam wskaznik przedostatniego elementu listy na NULL
free(aktu);
}
////////////////////////////////////////////////////////
void usun_srod(elist *lista, int miej){
elist *aktu=lista;
int i;
while (aktu->popr != NULL){
aktu = aktu->popr;
}
while (aktu->nast != NULL) {
if(i == miej){
(aktu->popr)->nast = aktu->nast;
(aktu->nast)->popr = aktu->popr;
free(aktu);
break;
}
i++;
aktu=aktu->nast;
}
}
//------------------------------------------------------
//-------------- OBSLUGA PLIKOW ------------------------
//------------------------------------------------------
//------------------------------------------------------
//----------- MENU I OBSLUGA PROGRAMU ------------------
//------------------------------------------------------
//---------------- PROGRAM -----------------------------
int main(){
elist *a;
a=(elist*)malloc(sizeof(elist));
a->nast=NULL;
a->popr=NULL;
a->wartosc = 5;
dodaj_pocz(a,3);
dodaj_kon(a,10);
dodaj_kon(a,30);
dodaj_pocz(a,50000);
dodaj_pocz(a,0);
dodaj_pocz(a,18);
dodaj_srod(a,1111,4);
wypisz_liste(a);
printf("\n");
//usun_pocz(a);
usun_kon(a);
//usun_srod(a,1);
wypisz_liste(a);
return 0;
}
(usuwanie ze środka też nie działa, chociaż nie wywala błędu, ale to na dalszy plan zostawiam :) )
A tu wklejam sam problematyczny fragment:
////////////////////////////////////////////////////////
void usun_kon(elist *lista){
elist *aktu=lista;
while (aktu->nast != NULL){
aktu = aktu->nast; // Jesli dobrze rozumiem to:
}// whilem przechodze na koniec listy
(aktu->popr)->nast=NULL; //ustawiam wskaznik przedostatniego elementu listy na NULL
free(aktu);
Problemem jest dla kompilatora ten fragment
(aktu->popr)->nast=NULL;
. Gdy usuwam tę linijkę wszystko ładnie działa, dodaję ją i kompletna klapa. Próbowałem użyć dodatkowego wskaźnika, wskazującego na element usuwany a dopiero potem zwolnić pamięć lecz efekt ten sam. Niestety skończyły mi się pomysły :(
Z góry dzięki za pomoc.