C, cancellare un elemento da una SCL

di Anonimizzato14377 il
5 risposte
Devo implementare questa funzione:

void set_difference(setSCL* set1, setSCL set2);
/*dato un puntatore set1 ad insieme ed un
insieme set2, elimina dall'insieme puntato da
set1 gli eventuali elementi presenti anche in set 2;*/


Nel main richiamo la funzione in questo modo:

set_difference(&insieme, sotto_insieme);


Ed ecco la funzione:
void set_difference(setSCL* set1, setSCL set2)
{
	setSCL insieme = *set1, insieme_temp, salva_punt; 
	int temp, esterno = 1, interno = 1;
	
	while(set2 != NULL)
	{
		printf("Ciclo esterno %d\n", esterno);
		interno = 1;
		temp = set2 -> elemento;
		printf("\ttemp: %d\n", temp);

		while(insieme != NULL)
		{
			printf("\tCiclo interno %d\n", interno);
			printf("\t\tinsieme -> elemento = %d\n", insieme -> elemento);
			if(temp == insieme -> next -> elemento)
			{
				printf("if\n");
				insieme_temp = insieme -> next;
				insieme -> next = insieme -> next -> next;
				free(insieme_temp);
	
	
			}
			else
			{
				printf("else\n");
				insieme = insieme -> next;
				interno++;
			}

		}
		set2 = set2 -> next;
		esterno++;
		
	}
}
La quale, però, mi da un Errore di segmentazione (core dump creato)


In particolar modo mi stampa:

Elemento 1 dell'insieme: 1
Elemento 2 dell'insieme: 2
Elemento 3 dell'insieme: 6

Elemento 1 del sottoinsieme: 1
Elemento 2 del sottoinsieme: 2

Ciclo esterno 1
temp: 2
Ciclo interno 1
insieme -> elemento = 6
if
Ciclo interno 2
insieme -> elemento = 6
else
Ciclo interno 3
insieme -> elemento = 1
Errore di segmentazione (core dump creato)


Chi mi aiuta a trovare l'errore? Grazie

5 Risposte

  • Prima di utilizzare insieme->next (genericamente, qualsiasi 'next') dovresti SEMPRE verificare che non sia NULL...
  • In che punto della funzione?

    Ci ho lavorato ancora un po' su ma funziona 1 volta sì e 100 no..
    
    void set_difference(setSCL* set1, setSCL set2)
    {
    	setSCL insieme = *set1, insieme_temp, salva_punt; 
    	int temp, esterno = 1, interno = 1;
    	
    	while(set2 != NULL)
    	{
    		printf("Ciclo esterno %d\n", esterno);
    		interno = 1;
    		temp = set2 -> elemento;
    		printf("\ttemp: %d\n", temp);
    
    		while(insieme -> next != NULL)
    		{
    			printf("\tCiclo interno %d\n", interno);
    			printf("\t\tinsieme -> elemento = %d\n", insieme -> elemento);
    			if(temp == insieme -> elemento)
    			{
    				printf("if(temp == insieme -> elemento)\n");
    				insieme_temp = insieme;
    				insieme = insieme -> next;
    				free(insieme_temp);
    				
    			}
    			else
    				if(temp == insieme -> next -> elemento)
    				{
    					printf("if(temp == insieme -> next -> elemento)\n");
    					setSCL del;
    					del = insieme -> next;
    					insieme -> next = insieme -> next -> next;
    					free(del);
    					//interno++;
    				}
    				else
    					if((temp == insieme -> elemento)&&(insieme -> next -> next == NULL))
    					{
    						printf("((temp == insieme -> elemento)&&(insieme -> next -> next == NULL))\n");
    						free(insieme -> next);
    						insieme -> next = NULL;
    					}
    				
    			insieme = insieme -> next;
    			interno++;
    
    		}
    		set2 = set2 -> next;
    		esterno++;
    		
    	}
  • In che punto della funzione?
    Ovunque. Siccome next potrebbe essere NULL (ad indicare la fine della lista) bisognerebbe sempre verificarne il suo valore prima di utilizzarlo come puntatore.
  • Ok, ora ci provo.. Nel frattempo saresti così gentile da dare un'occhiata al codice? L'algoritmo va migliorato perché, come ti ho detto, il più delle volte non funziona. Il problema è che le ho provate tutte e non so più che inventarmi..
  • Il problema è che le ho provate tutte e non so più che inventarmi..
    Non devi lavorare "per tentativi".
    Prima di tutto devi definire "su carta" la sequenza di passi, anche in pseudocodice, e verificare "a mano" che l'algoritmo sia corretto (considerando tutta una serie di input iniziali); dopodichè lo codifichi in C e ne fai la verifica finale.
Devi accedere o registrarti per scrivere nel forum
5 risposte