[Algoritmi] Problema con liste concatenate
Bonasera a tutti. Sto simulando una playlist di film realizzata con una lista doppiamente concatenata in c. Ho anche realizzato una funzione per stampare un nodo della playlist e un'intera playlist. Il problema è che questa stampa allinfinito. Potreste aiutarmi a capire dov'è il problema?
#include <stdio.h> #include <stdlib.h> #include <string.h> #define DIM_TITLE 50 #define DIM_GENRE 50 #define DIM_NAME 50 typedef struct { char title[DIM_TITLE]; char genre[DIM_GENRE]; int num_episodes; struct TVS* prev; struct TVS* next; } TVS; typedef struct { char name[DIM_NAME]; TVS* top; } PlayList; void insertTvSeries(PlayList *pl, TVS *t) { if(pl->top == NULL) { pl->top = t; t->next = NULL; t->prev = NULL; return; } else { TVS *tmp_prev = pl->top; // = NULL TVS *tmp_next = pl->top; while(tmp_next->next != NULL && (strcmp(tmp_next->title, t->title) <= 0)) { tmp_prev = tmp_next; tmp_next = (TVS *) tmp_next->next; } if(tmp_next->next == NULL) { tmp_prev->next = t; // == tmp_next = t t->prev = tmp_next; t->next = NULL; //tmp_prev->prev = pl->top; } else if(strcmp(tmp_prev->title, t->title) > 0) { TVS *nodo1 = pl->top; t->next = nodo1; t->prev = pl->top; nodo1->prev = t; pl->top->next = t; } else { t->prev = tmp_prev; t->next = tmp_next; tmp_next->prev = t; tmp_prev->next = t; } } } void printTVSeries(TVS* t) { printf("TITLE :\t %s \n", t->title); printf("GENRE :\t %s \n", t->genre); printf("EPISODES :\t %d \n\n", t->num_episodes); } void printPlaylist(PlayList *pl) { TVS* serie = pl->top; while(serie != NULL) { printTVSeries(serie); serie = serie->next; } } int main() { PlayList p; strcpy(p.name, "My own TV Series"); p.top = NULL; TVS t1 = {"abra", "ss", 1}; TVS t2 = {"ebra", "sr", 2}; TVS *tp1 = &t1; TVS *tp2 = &t2; insertTvSeries(&p, tp1); insertTvSeries(&p, tp2); printPlaylist(&p); return 0; }
Risposte
Aggiornamento: ho provato a riavviare il pc e il problema è sparito. Sarebbe interessante capire perchè.
clang (con l'address sanitizer attivo) si lamenta che
Si lamenta anche di strcpy, ma quello è basato sul fatto che ho compilato su windows son la libreria di Microsoft.
Nota che il mio editor chiama [inline]clang-format[/inline] quando salvo, quindi le righe possono non essere le stesse.
Penso che il problema è che [inline]TVS[/inline] è un typedef di una struct che non si chiama [inline]TVS[/inline] (è anonima). Puoi risolvere dandole un nome.
Detto questo, mi stupirebbe se creasse molti problemi.
Non ho controllato tutto, ma ho qualche dubbio sul funzionamento dell'inserimento dell'elemento. Ma ci devo ragionare su.
> clang -std=c17 -O1 -g -fsanitize=address -fno-omit-frame-pointer .\matematicamente.c .\matematicamente.c:49:28: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] tmp_prev->next = t; // == tmp_next = t ^ ~ .\matematicamente.c:50:21: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] t->prev = tmp_next; ^ ~~~~~~~~ .\matematicamente.c:58:21: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] t->next = nodo1; ^ ~~~~~ .\matematicamente.c:59:21: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] t->prev = pl->top; ^ ~~~~~~~ .\matematicamente.c:60:25: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] nodo1->prev = t; ^ ~ .\matematicamente.c:61:27: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] pl->top->next = t; ^ ~ .\matematicamente.c:66:21: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] t->prev = tmp_prev; ^ ~~~~~~~~ .\matematicamente.c:67:21: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] t->next = tmp_next; ^ ~~~~~~~~ .\matematicamente.c:68:28: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] tmp_next->prev = t; ^ ~ .\matematicamente.c:69:28: warning: incompatible pointer types assigning to 'struct TVS *' from 'TVS *' [-Wincompatible-pointer-types] tmp_prev->next = t; ^ ~ .\matematicamente.c:90:15: warning: incompatible pointer types assigning to 'TVS *' from 'struct TVS *' [-Wincompatible-pointer-types] serie = serie->next; ^ ~~~~~~~~~~~
Si lamenta anche di strcpy, ma quello è basato sul fatto che ho compilato su windows son la libreria di Microsoft.
Nota che il mio editor chiama [inline]clang-format[/inline] quando salvo, quindi le righe possono non essere le stesse.
Penso che il problema è che [inline]TVS[/inline] è un typedef di una struct che non si chiama [inline]TVS[/inline] (è anonima). Puoi risolvere dandole un nome.
typedef struct TVS_s { char title[ DIM_TITLE ]; char genre[ DIM_GENRE ]; int num_episodes; struct TVS_s* prev; struct TVS_s* next; } TVS;
Detto questo, mi stupirebbe se creasse molti problemi.
Non ho controllato tutto, ma ho qualche dubbio sul funzionamento dell'inserimento dell'elemento. Ma ci devo ragionare su.
Se scambi le chiamate a insertTvSeries, mi stampa:
che conferma i miei sospetti che ti sei dimenticato del caso in cui devi aggiornare il top.
Io lo avrei scritto così, mi sembra che tu abbia complicato la logica.
TITLE : ebra GENRE : sr EPISODES : 2 TITLE : abra GENRE : ss EPISODES : 1
che conferma i miei sospetti che ti sei dimenticato del caso in cui devi aggiornare il top.
Io lo avrei scritto così, mi sembra che tu abbia complicato la logica.
void insertTvSeries( PlayList* pl, TVS* t ) { // la lista è vuota oppure può essere inserito all'inizio if ( pl->top == NULL || ( strcmp( t->title, pl->top->title ) <= 0 ) ) { t->next = pl->top; t->prev = NULL; pl->top = t; return; } TVS* tmp_prev = pl->top; TVS* tmp_next = pl->top->next; // find where to add it while ( tmp_next != NULL && ( strcmp( tmp_next->title, t->title ) < 0 ) ) { tmp_prev = tmp_next; tmp_next = tmp_next->next; } t->next = tmp_next; t->prev = tmp_prev; tmp_prev->next = t; if ( tmp_next != NULL ) { tmp_next->prev = t; } }
Grazie mille Vict!