[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!