[C] Operazione insiemistica su lista

petrogass
Ho dei problemi a far funzionare questo programma. Esso dovrebbe essere in grado di scorrere un array di interi V, e data una lista collegata con puntatori con un campo position ordinato in modo crescente partendo 1, rimuovere dalla lista l'elemento col campo position uguale al valore presente nell'array e collegarlo in coda ad una seconda lista. Il problema è che sembra che il programma non riesca ad assegnare position e a causa di ciò il programma termina prematuramente quando confronta il valore nell'array con position all'inizio della funzione detach. Mi scuso per la confusione del codice e ringrazio se qualcuno è in grado di darmi una mano.
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
typedef unsigned short int boolean;

struct list{
	float value;
	int position;
	struct list *next_ptr;
};

void init (struct list **ptrptr);
boolean detach(struct list **ptr1, struct list **ptr2, int *V, int N);
void pre_insert(struct list **ptrptr, float value, int position);
void suf_insert(struct list **ptrptr, float value, int position);
void visit(struct list *ptr);

int main (){
	setvbuf (stdout, NULL, _IONBF,0);
	int *V;
	int N;
	int S;
	float value;
	printf("Inserire dimensione: \n");
	scanf("%d", &N);
	V=(int*)malloc(N*sizeof(int));
	int count;
	for(count=0; count<N; count++){
		printf("Inserire elemento numero %d \n", count+1);
		scanf("%d", &V[count]);
	}

	struct list **ptr1;
	struct list **ptr2;
	init(&ptr2);
	init(&ptr1);

	printf("Inserire dimensione lista: \n");
	scanf("%d", &S);

	for(count=0; count<S; count++){
		printf("Inserire elemento numero %d \n", count+1);
		scanf("%f", &value);
		suf_insert(&ptr1, value, count+1);
	}
	detach(ptr1, ptr2, V, N);
	visit(ptr2);
}

boolean detach(struct list **ptr1, struct list **ptr2, int *V, int N){
	if(*ptr1!=NULL){
		int i=0;
		struct list *tmp_ptr;
		while(*ptr1!=NULL){
			if(V[i]==((*ptr1)->position)){

				tmp_ptr=*ptr1;
				*ptr1=(*ptr1)->next_ptr;

				tmp_ptr->next_ptr=*ptr2;
				ptr2=&((tmp_ptr)->next_ptr);
			}
			else
				ptr1=&((*ptr1)->next_ptr);
			i++;
		}
		return TRUE;
	}
	else
		return FALSE;
}



void init (struct list **ptrptr){
	*ptrptr=NULL;
}

void pre_insert(struct list **ptrptr, float value, int position){
	struct list *tmp_ptr;
	tmp_ptr=*ptrptr;
	*ptrptr=(struct list*)malloc(sizeof(struct list));
	(*ptrptr)->value=value;
	(*ptrptr)->position=position;
	(*ptrptr)->next_ptr=tmp_ptr;

}

void suf_insert(struct list **ptrptr, float value, int position){
	while(*ptrptr!=NULL)
		ptrptr=&((*ptrptr)->next_ptr);
	pre_insert(ptrptr, value, position);
}


void visit (struct list *ptr){
	while(ptr!=NULL){
		printf("%f \n", ptr->position);
		ptr=ptr->next_ptr;
	}
}


Risposte
apatriarca
Compilando il tuo codice mi vengono dati alcuni errori (ci sono in diverse righe..):
Type error in argument 1 to 'init'; expected 'struct list * *' but found 'struct list * * *'.
Type error in argument 1 to 'suf_insert'; expected 'struct list * *' but found 'struct list * * *'.
Type error in argument 1 to 'visit'; expected 'struct list *' but found 'struct list * *'.

L'errore è sempre lo stesso. Hai una variabile di un certo tipo e una funzione che prende come parametro quel tipo, ma tu stai passando la variabile usando &..

petrogass
Quelli là son dei semplici warning del compilatore ma il codice associato a quelle cose funziona bene. Con una leggera modifica l'array e la lista vengono creati in modo corretto, ma il problema persiste e il programma viene terminato al momento della chiamata alla funzione detach. Forse passo male le liste e l'array, ma non riesco a capire dove sbaglio.

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
typedef unsigned short int boolean;

struct list{
	float value;
	int position;
	struct list *next_ptr;
};

void init (struct list **ptrptr);
boolean detach(struct list **ptr1, struct list **ptr2, int *V, int N);
void pre_insert(struct list **ptrptr, float value, int position);
void suf_insert(struct list **ptrptr, float value, int position);
void visit(struct list *ptr);

int main (){
	setvbuf (stdout, NULL, _IONBF,0);
	int *V;
	int N;
	int S;
	float value;
	printf("Inserire dimensione: \n");
	scanf("%d", &N);
	V=(int*)malloc(N*sizeof(int));
	int count;
	while(count<N){
		printf("Inserire elemento numero %d \n", count+1);
		scanf("%d", &V[count]);
		count++;
	}

	struct list **ptr1;
	struct list **ptr2;
	init(&ptr2);
	init(&ptr1);

	printf("Inserire dimensione lista: \n");
	scanf("%d", &S);

	for(count=0; count<S; count++){
		printf("Inserire elemento numero %d \n", count+1);
		scanf("%f", &value);
		suf_insert(&ptr1, value, count+1);
	}
	detach(ptr1, ptr2, V, N);
	visit(ptr2);
}

boolean detach(struct list **ptr1, struct list **ptr2, int *V, int N){
	if(*ptr1!=NULL){
		int i=0;
		struct list *tmp_ptr;
		while(*ptr1!=NULL){
			if(V[i]==((*ptr1)->position)){

				tmp_ptr=*ptr1;
				*ptr1=(*ptr1)->next_ptr;

				tmp_ptr->next_ptr=*ptr2;
				ptr2=&((tmp_ptr)->next_ptr);
			}
			else
				ptr1=&((*ptr1)->next_ptr);
			i++;
		}
		return TRUE;
	}
	else
		return FALSE;
}



void init (struct list **ptrptr){
	*ptrptr=NULL;
}

void pre_insert(struct list **ptrptr, float value, int position){
	struct list *tmp_ptr;
	tmp_ptr=*ptrptr;
	*ptrptr=(struct list*)malloc(sizeof(struct list));
	(*ptrptr)->value=value;
	(*ptrptr)->position=position;
	(*ptrptr)->next_ptr=tmp_ptr;

}

void suf_insert(struct list **ptrptr, float value, int position){
	while(*ptrptr!=NULL)
		ptrptr=&((*ptrptr)->next_ptr);
	pre_insert(ptrptr, value, position);
}


void visit (struct list *ptr){
	while(ptr!=NULL){
		printf("%f \n", ptr->value);
		ptr=ptr->next_ptr;
	}
}


apatriarca
NON sono dei semplici warning. Sono ERRORI e senza correggerli mi è impossibile compilare il codice. Il tuo codice non è un corretto e funziona per puro caso (un puntatore a puntatore e un puntatore sono alla fin fine più o meno la stessa cosa ed essendo coerente nel fare questo errore alla fine tutto funziona). In generale, evitare i warning è una pessima abitudine che conviene eliminare al più presto. È spesso nei warning che si cela l'errore. Il secondo codice è stato modificato rispetto al primo?

petrogass
Cambiando in modo da far contento il compilatore il programma va in crash

apatriarca
Dipende da cosa cambi.. Cambiando il tipo delle variabili non c'è alcun problema. Ottengo il problema che hai descritto tu.

vict85
Immagino sia un compito dato che nessuno sano di mente implementerebbe qualcosa di quel tipo. Ci sono delle parti che sono fatti dal professore oppure è tutto stato scritto da te? Lo dico solo per sapere dove evitare di toccare.

petrogass
init, pre_insert, suf_insert e visit le ho prese così come sono sul libro, il resto è mio

apatriarca
Per prima cosa la funzione detach non verifica che \(i\) sia minore della dimensione dell'array. Questo potrebbe causare problemi. La rimozione dei nodi dalla lista è poi errato. Dovresti aggiornare il nodo precedente a quello che rimuovi in modo che il suo puntatore next punti al nodo successivo del nodo eliminato. È infine errato il codice per inserire il nodo rimosso nella seconda lista. Perché non fai uso delle funzioni che hai già a disposizione?

petrogass
Perché in detach non posso allocare o deallocare memoria, da testo del compito. Grazie per gli errori che mi hai fatto notare, ma il problema principale è che non riesco a fare un doppio ciclo in cui in uno scorre count e l'altro *ptr1. Vict85, sei arrivato a capo di qualcosa?

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.