ho un problema col codice che vi posto
main.c
Codice: Seleziona tutto
#include "header.h"
#include "strutture.h"
/* Funzione per deallocare memoria. Gli viene passata una struttura di liste
e una variabile intera che indica quante liste ci sono. */
void dealloca_memoria(struct list* list, int numListe){
int i; /* Indice per scorrere le liste */
for(i = 1; i <= numListe; i++){ /* Ciclo che scorre tutte le liste fino a quel momento create */
free(list->next); /* per ogni lista libero lo spazio che avevo allocato */
list = list -> next; /* passo alla lista successiva */
}
printf("Memoria liberata da %d liste\n", numListe);
}
int main (void){
int iGuardia; /* Contiene un valore che mi dice se l'inserimento e' valido o no. */
int iContList=0;/* Contatore di liste presenti in memoria. */
int iElementoDellaLista; /* Contiene l'elemento, inserito dall'utente, da inserire nella lista. */
int k; /* Contiene il valore di K come richiesto dalla specifica. */
char aczNameOfList[100]; /*Contiene il nome di una lista inserito dall'utente al punto b. */
char cScelta; /* Contiene la scelta effettuata dall'utente. */
struct list* first = init_list();
struct list* last_list = first;
while(1){
cScelta=stampaMenu();
switch (cScelta){
case 'a':
printf("Inserisci gli elementi della lista.\n 0 per terminare l'inserimento\n\n");
iContList++;
last_list = insert_list(last_list, iContList);
printf("\nElemento: ");
iGuardia = scanf("%d", &iElementoDellaLista);
if(iGuardia!=1){ /* Se è vero vuol dire che ho inserito un input errato, dunque richiedo l'inserimento. */
do{
printf("Input errato!!\nElemento: ");
while (getchar() != '\n');
iGuardia = scanf("%d", &iElementoDellaLista);
}while(iGuardia != 1);
}
while(iElementoDellaLista!=0){ /* Chiedo l'inserimento di elementi fino a quando non inserisco lo 0.*/
insert_node(last_list, iElementoDellaLista); /* Ogni elemento che inserisco lo salvo nella lista. */
printf("Elemento: ");
iGuardia = scanf("%d", &iElementoDellaLista);
if(iGuardia!=1){
do{
printf("Input errato!!\nElemento: ");
while (getchar() != '\n');
iGuardia = scanf("%d", &iElementoDellaLista);
}while(iGuardia!=1);
}
}
break;
case 'v':
if(iContList==0){
printf("Non ci sono liste da stampare\n");
break;
}else{
print_allList(first, iContList);
}
break;
case 'b':
printf("Inserisci il nome di una lista (nel formato List-i) a cui applicare lo split: ");
scanf("%s", aczNameOfList);
iContList = listPresentOrNotPresent(first, aczNameOfList, iContList);
print_allList(first, iContList);
break;
case 'c':
do{
printf("Inserisci un valore intero positivo(maggiore di 1): ");
scanf("%d", &k);
}while(k<=1);
iContList = split_k_diTutteLeListe(first, k, iContList);
print_allList(first, iContList);
break;
case 'd':
printf("\nEsecuzione terminata\n\n");
dealloca_memoria(first, iContList); /* Chiamata alla funzione per liberare la memoria dalle liste create */
system("make clean"); /* Prima di uscire faccio la pulizia della directory dei file di esecuzione temporanei */
exit(EXIT_SUCCESS); /* provoca la conclusione corretta del programma */
}
}
}
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
char stampaMenu(void); /* Dichiarazione di stampaMenu che restituisce un char (la scelta) e non prende
valori, per questo è stato messo esplicitamente void nelle parentesi,
come richiesto dallo standard ANSI. */
struct list *init_list (); /* Mi fa l'iniziliazzazione della lista. */
struct list* insert_list(struct list*, int contList); /* Mi permette di inserire nuove liste. */
Codice: Seleziona tutto
#include "header.h"
/*
* Funzione che stampa il menu di selezione.
* L'utente inserisce da tastiera la scelta, sulla quale viene fatto
* il controllo che sia una scelta corretta, altrimenti si richiede
* di rieffettuare la scelta.
*/
char stampaMenu(void){
char cScelta; // Variabile che contiene la scelta effettuata
printf("\n\nMENU DI SCELTA\n");
printf("a) Creazione di una nuova lista di interi.\n");
printf("v) vedi liste\n");
printf("b) Split k di una lista List-i.\n");
printf("c) Split k di tutte le liste.\n");
printf("d) Stampa un messaggio di uscita e esce dal programma.\n");
printf("Fai una scelta: ");
do{
scanf("%c", &cScelta); // Inserisco la scelta nella variabile.
}while(!(cScelta=='a' || cScelta=='b' || cScelta=='c' || cScelta=='d' || cScelta=='v'));
return cScelta; // restituisco la variabile con la scelta fatta.
}
Codice: Seleziona tutto
#include "header.h"
#include "strutture.h"
/**
* Funzione che mi permette di stampare
* la lista passata come argomento.
*/
void print_list(struct list* list){
int i;
struct node* tempNode;
tempNode = list -> header;
if(list -> iNumeroElementi == 0){ /* Se la lista non ha elementi */
printf("\n%s: Nil", list -> cNomeLista); /* Stampo Nil */
}else{
printf("\n%s: [", list -> cNomeLista);
for(i = 0; i < list -> iNumeroElementi; i++){ /* Ciclo for che stampa uno per uno tutti gli elementi della lista*/
printf(" %d ", tempNode->iData);
tempNode = tempNode -> next;
}
printf("]");
}
}
/**
* Funzione che stampa tutte le liste
* che sono state create e che sono
* presenti in memoria. Ogni lista
* presente in memoria viene passata come
* argomento alla funzione print_list
* che si occupa di stamparla.
*/
void print_allList(struct list* list, int iNumListe){
int i=0;
printf("iNumListe vale: %d\n", iNumListe);
for(i = 0; i < iNumListe; i++){
list = list -> next;
print_list(list/*->next*/);
//list = list -> next;
}
/*while(list -> next != NULL){
i = i + 1;
list = list -> next;
}*/
printf("liste in memoria: %d\n", i);
}
void printNameOfAllList(struct list *list, int contList){
int i;
for(i=0; i < contList; i++){
list = list -> next;
printf("\n%s", list -> cNomeLista);
}
}
int split_k_diUnaLista(int x, struct list* list, int k, int iContList){
int i;
int j;
int iElemento;
struct node* tempNode = list -> header; /* Assegno a tempNode la testa della lista passata come argomento */
struct node* tempNode2 = list -> header; /* tempNode2 lo uso per lavorare con la nuova lista creata a partire da quella passata per argomento. */
struct list* newList = list; /* Dichiarazione una nuova lista*/
while(newList -> next != NULL){ /* Ciclo che mi serve per spostarmi all'ultima lista presente in memoria. */
newList = newList -> next;
}
iContList = iContList + 1; /* Incremento il contatore del numero di liste presenti in memoria */
newList = insert_list(newList, iContList); /* Faccio l'inserimento della nuova lista in memoria. */
for(i=0; i < list -> iNumeroElementi; i++){
if(i == x){ //appena l'indice i e' uguale al valore calcolato x
for(j=i; j < list -> iNumeroElementi; j++){ /* Scorro la lista a partire dall'elemento indicato
dall'indice x calcolato*/
iElemento = tempNode2 -> iData; /* Prendo l'elemento corrispondente */
insert_node(newList, iElemento); /* e lo inserisco nella nuova lista */
tempNode2 = tempNode2 -> next; /* Passo all'elemento successivo. */
}
tempNode = tempNode -> next = NULL; /* Metto l'elemento successivo a quello indicato dall'indice i*/
list -> iNumeroElementi = x; /* Modifico la lunghezza della lista originale passata come argomento. */
break; //interrompo il ciclo for
}
tempNode = tempNode -> next;
tempNode2 = tempNode2 -> next;
}
k = k - 1; /* Decremento k che sarebbe il numero di nuove liste da creare*/
if(k>1){
iContList = split_k_diUnaLista(x, newList, k, iContList); /* Chiamata ricorsiva passando come argomenti il solito
valore di x, la nuova lista calcolata, il valore di k aggiornato
e iContList aggiornato*/
}
return iContList;
}
int split_k_diTutteLeListe(struct list* list, int k, int iContList){
int i;
int x;
int temp = iContList;
list = list -> next;
for(i=0; i < temp; i++){ /* Uso temp come guardia perche' iContList viene modificato e si andrebbe in errore. */
if(list -> iNumeroElementi != 0){ /* Per ogni lista che contiene almeno un elemento, */
x = (list -> iNumeroElementi)/k; /* calcolo il valore della x secondo le specifiche del testo. */
iContList = split_k_diUnaLista(x, list, k, iContList);/* E ogni lista presente in memoria la passo come argomento
alla funzione dell'esercizio al punto b. */
list = list -> next; /* Passo alla lista successiva. */
}else{
list = list -> next; /* Se la lista attuale contiene 0 elementi, quindi Nil, passo
alla lista successiva. */
}
}
return iContList; /* Ritorno il valore di iContList aggiornato (cioe' il numero di liste presenti in memoria dopo
aver chiamato le funzioni sopra). */
}
/**
* Funzione che controlla se il nome di lista
* inserito corrisponde con un nome di lista
* presente in memoria.
*/
int listPresentOrNotPresent(struct list* list, char *sEnteredName, int iContList){
int i; /* indice del ciclo for */
int k; /* valore richiesto dal testo dell'esercizio */
int x; /* valore calcolato secondo le specifiche dell'esercizio */
int notPresent = 0;
for(i=0; i < iContList; i++){ //scorro tutte le liste a partire dalla prima alla ricerca di quella inserita in input
list = list -> next;
if(strcmp(list -> cNomeLista, sEnteredName)==0){ //verifico che il nome della lista corrisponde a quello da me inserito
notPresent = 1;
if(list -> iNumeroElementi == 0) { //se la lista contiene 0 elementi (Nil) stampo un messaggio e esco.
printf("Split non applicabile ad una lista vuota!\n");
break;
}
do{ /* Se la lista esiste chiedo di inserire il valore di k, controllando di inserire un valore > 1. */
printf("Inserisci un valore intero positivo(maggiore di 1): ");
scanf("%d", &k);
}while(k<=1);
x = (list -> iNumeroElementi)/k; /* Calcolo il valore della x secondo le specifiche del testo */
iContList = split_k_diUnaLista(x, list, k, iContList); /* chiamo la funzione per effettuare lo split sulla lista inserita in input con il valore di k inserito in input. */
break;
}
}
if (notPresent != 1) printf("Lista non trovata\n"); /* Se il nome che inserisco non si trova in memoria, stampo un messaggio informativo. */
return iContList;
}
/**
* Funzione che, se richiamata, mi permette di
* di inizilizzare la lista.
*/
struct list* init_list (){
printf("Inizializzo la struttura delle liste\n");
struct list *temp;
temp = malloc(sizeof(struct list));
temp -> iNumeroElementi=0;
temp -> header = NULL;
temp -> tail = NULL;
temp -> next = NULL;
return temp;
}
/**
* Funzione che nserisce una nuova lista in memoria
* con nome nel formato List-iContList (che è progressivo).
*/
struct list* insert_list(struct list* list, int iContList){ //modifica
//creo una nuova lista
struct list *new_list;
//alloco spazio per la nuova lista
new_list = malloc(sizeof(struct list));
sprintf(new_list -> cNomeLista, "List-%d", iContList);
new_list -> iNumeroElementi = 0;
new_list -> header = NULL;
new_list -> tail = NULL;
list -> next = new_list;
new_list -> next = NULL;
return new_list;
}
Codice: Seleziona tutto
#include "strutture.h"
#include "header.h"
void insert_node(struct list *list, int iElemento){
//creo un nuovo nodo
struct node *new_node;
//alloco spazio per il nuovo nodo
new_node = malloc(sizeof(struct node));
new_node -> iData = iElemento;
new_node -> next = NULL;
if(list -> iNumeroElementi==0){
new_node -> prev = NULL;
list -> header = new_node;
}else{
new_node -> prev = list -> tail;
list -> tail -> next = new_node;
}
list -> tail = new_node;
list -> iNumeroElementi++;
}
int scan_node(struct list* list, int indice){
indice--;
if(indice >= list -> iNumeroElementi){
printf("Errore: hai inserito un indice che supera le dimensioni della lista");
return 0;
}
int i;
int iElemento;
struct node* tempNode;
tempNode = list -> header;
for(i = 0; i < list -> iNumeroElementi; i++){
if(i == indice){
iElemento = tempNode -> iData;
return iElemento;
}
tempNode = tempNode -> next;
}
return 0;
}
Codice: Seleziona tutto
struct node{
int iData;//elemento della lista
struct node *prev; //puntatore all'elemento precedente della lista;
struct node *next; //puntatore all'elemento successivo della lista;
};
struct list {
char cNomeLista[10]; //array contenente il nome della lista
int iNumeroElementi; //numero elementi della lista
struct node *header; //puntatore al primo elemento della lista
struct node *tail; //puntatore all'ultimo elemento della lista
struct list *next; //puntatore alla successiva lista
};
I punti ( b ) e ( c ) quando richiamati fanno il loro dovere secondo le specifiche del testo, il problema nasce se, dopo aver chiamato ( b ) o ( c ) chiamo ( a ) per inserire una nuova lista, a questo punto anche se chiamo semplicemente ( v ) per stampare le liste in memoria mi da
Codice: Seleziona tutto
Segmentation fault ( core dumped)
Inserisco le liste
Codice: Seleziona tutto
List-1: [ 33 -44 55 123 12 ]
List-2: [ 11 13 ]
List-3: Nil
List-4: [ 1 ]
Codice: Seleziona tutto
Inserisci un valore intero positivo(maggiore di 1): 3
iNumListe vale: 10
List-1: [ 33 ]
List-2: Nil
List-3: Nil
List-4: Nil
List-5: [ -44 ]
List-6: [ 55 123 12 ]
List-7: Nil
List-8: [ 11 13 ]
List-9: Nil
List-10: [ 1 ]
Codice: Seleziona tutto
Fai una scelta: v
iNumListe vale: 11
List-1: [ 33 ]
List-2: Nil
List-3: Nil
List-4: Nil
Segmentation fault (core dumped)