salve a tutti. sto cercando di risolvere un programma in C ma non riesco a capire dove sbaglio



codice:
typedef struct Elem {
    long         val;
    char *       str;   // stringa allocata dinamicamente
    struct Elem *next;
} Elem, *List;
Praticamente deve analizzare la Lista A e se trova almeno un elemento con lo stesso value in B concatena le stringhe in A, altrimenti cancella dalla lista A l'elemento.

Esempio:

A = 2.Rosso -> 1.Verde -> 3.Giallo -> 1.Nero -> 7.Viola
B = 5.Mela 3.Gatto -> 1.Cane -> 1.Tigre -> 1.Pera

il risultato è

A= 1.VerdeCaneTigrePera -> 3.GialloGatto -> 1.NeroCaneTigrePera

B Rimane invariato.

il problema è come ho scritto il programma io fa tutti i passaggi correttamente, ma quando trova un nuovo elemento da concatenare mi sovrascrive quello prima

per esempio con gli stessi input di prima, con il mio programma ora l'output è:

1.NeroCaneTigrePera -> 1.NeroCaneTigrePera -> 1.NeroCaneTigrePera

Qualcuno di voi riesce ad aiutarmi e sa dove sbaglio?
grazie


codice:
List join( List A, List B ){
	
	if( A == NULL || B == NULL ) return 0;
	int trovato = 0, nc = 0; // "trovato" mi dice se è stato trovato un val uguale. nc mi mantiene la dimensione della stringa concatenata
	char *s; // stringa d'appoggio
	char *concat = NULL; // stringa concatenata
	Elem **pp = &A;
	while( *pp != NULL ){
		
		Elem *p = *pp; // per i valori della lista A
		Elem *e = B; // per scorrere la lista B
		while( e != NULL ){
			
			if( e -> val == p -> val ){ // se trovo un val uguale
				
				trovato = 1; // trovato
				s = malloc( strlen( e -> str ) + 1 ); // le prossime istruizioni mi creo la stringa concatenata e la metot in p->str
				strcpy( s, e -> str );
				nc = strlen( p -> str );
				concat = realloc( concat, nc + 1 );
				strcpy( concat, p -> str );
				int i =  0;
				while( s[i] != '\0' ){
					
					concat = realloc( concat, nc + 2 );
					concat[nc++] = s[i++];
				}
				
				
				free( s );
				concat[nc] = '\0';
				p -> str = concat; // qui
			}// fine if
			e = e -> next; 
		}// fine secondo while
		if( !trovato){ // se non ho trovato val uguali devo cancellare l'elemento della lista
			
			*pp = p -> next;
			free( p );
		}
		else{ // altrimenti passo al successivo e pongo trovato a 0
			pp = &( ( *pp ) -> next );
			trovato = 0;
		}
	}
	free( concat );
	return A;
}