Ciao, il segmentation fault indica che il tuo programma ha tentato di accedere ad un'area di memoria che non gli è riservata, quindi di fatto si tratta di un problema coi puntatori.
Guardando il tuo codice, infatti, puoi vedere che la prima volta in cui "
l1->n == l2-> n" crei un giustamente un nuovo elemento
l3 e gli assegni il valore
n. Dopodiché, però, ti prepari già un nuovo elemento (cioè l3->next,
che conterrà dei valori casuali), e questo è sbagliato perché non sai neanche se ci sarà un elemento successivo. Ad esempio se le liste hanno in comune 1 solo elemento, la lista l3 dovrà contenere 1 elemento, non 2.
L'istruzione che ti causa il segmentation fault, però, è
new->next=NULL;. Infatti poiché new punta a l3->next (che contiene valori casuali), quando fai new->next = NULL tenti di accedere ad un'area di memoria con indirizzo "casuale", cosa che ti causa il segmentation fault.
Il mio consiglio, quindi, è quello di crearti il nuovo elemento solo quando ne hai bisogno ed appenderlo in coda alla lista (puoi sfruttare una variabile che punti sempre all'ultimo elemento della lista
l3, un po' come hai fatto con
new).
Inoltre c'è un altro errore più subdolo: nei 2 cicli usi direttamente le variabili
l1 ed
l2, perdendo definitivamente (all'interno della funzione) i riferimenti agli inizi delle 2 liste. Per la lista
l1 questo non è un problema, ma per
l2 sì, in quanto ad ogni iterazione del ciclo su
l1 devi ricominciare a scandire
l2 dall'inizio. Per cui devi usare delle variabili indice:
nodo_t* i;
nodo_t* j;
for(i=l1; i!=NULL; i=i->next){
for(j=l2 ; j!=NULL; j=j->next) {
...
Inoltre da quanto ho capito sfrutti la variabile
acc esclusivamente per distinguere il caso in cui
l3 sia vuoto (cioè la prima occorrenza in cui
l1->n == l2->n) oppure no. In questo caso potresti semplicemente controllare se
l3 è NULL oppure no:
nodo_t* intersezione(nodo_t* l1, nodo_t* l2) {
nodo_t* l3 = NULL;
nodo_t* tail = NULL;
...
if (i->n == j->n) {
if (l3 == NULL) {
l3 = (nodo_t*) malloc(sizeof(nodo_t));
l3->n = i->n;
l3->next = NULL;
tail = l3;
} else {
// tail punta all'ultimo elemento valido di l3
nodo_t* tmp = (nodo_t*) malloc(sizeof(nodo_t));
tmp->n = i->n;
tmp->next = NULL;
tail->next = tmp;
tail = tail->next;
}
/*
* A questo punto se non ti servono gli elementi
* eventualmente ripetuti e' inutile continuare a controllare
* i successivi elementi, perche' ho gia' trovato
* un elemento di l2 uguale all'elemento corrente di l1.
* Per cui posso passare al successivo elemento di l1.
* Se, invece, vuoi anche gli elementi ripetuti il break
* va rimosso.
*/
break;
}
}