I want to delete the first Node of a list (I call it "head") but output give me an error "pointer being freed was not allocated". Do you know where is the issue? Sorry for Italian words if you didn't understand something I can edit my question. I think that the issue is in void cancellaTriangolo. Maybe I saved wrong nodes and they don't save themselves.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* STRUTTURE */
typedef struct punto {
int x;
int y;
} PUNTO;
typedef struct triangolo {
PUNTO v;
int lato;
} TRIANGOLO;
typedef struct nodo {
TRIANGOLO t;
struct nodo *next;
} NODO;
/* STAMPA LISTA */
int perimetro(TRIANGOLO t) {
return t.lato * 3;
}
void stampaTriangolo(TRIANGOLO t) {
printf("Il triangolo ha il lato uguale a: %d con un perimetro pari a %d, il vertice in alto ha coordinate (%d,%d)\n",
t.lato, perimetro(t), t.v.x, t.v.y);
}
void stampaLista(NODO *head) {
if (head->next == NULL) {
printf("Lista vuota!\n");
} else {
while (head->next != NULL) {
head = head->next;
stampaTriangolo(head->t);
}
}
}
/* INSERIMENTO */
TRIANGOLO creaTriangolo() {
TRIANGOLO nuovo;
printf("Inserisci il lato del nuovo triangolo: ");
scanf("%d", &nuovo.lato);
printf("\n");
printf("Inserisci le coordinate del vertice con y maggiore:\n");
printf("x: ");
scanf("%d", &nuovo.v.x);
printf("\n");
printf("y: ");
scanf("%d", &nuovo.v.y);
printf("\n");
return nuovo;
}
void inserisciPerPerimetro(NODO *head) {
NODO *nuovo = malloc(sizeof(NODO));
nuovo->t = creaTriangolo();
nuovo->next = NULL;
if (head == NULL) {
head = nuovo;
} else {
if (perimetro(nuovo->t) < perimetro(head->t)) {
nuovo->next = head;
head = nuovo;
} else {
while (head->next != NULL && perimetro(head->next->t) < perimetro(nuovo->t)) {
head = head->next;
}
nuovo->next = head -> next;
head->next = nuovo;
}
}
printf("Inserimento effettuato!\n\n");
}
/* CANCELLAZIONE IN TESTA */
void cancellaTriangolo(NODO *head) {
NODO *primoNodo = NULL;
/* lista vuota? */
if (head == NULL) {
primoNodo = NULL;
printf("Lista vuota!\n\n");
} else {
primoNodo = head;
head = head->next;
free(primoNodo);
printf("Cancellazione effettuata!\n");
}
}
int main() {
/* inizializza la lista */
NODO *head = malloc(sizeof(NODO));
head->next = NULL;
int risposta = -1; // per interazione con utente
while (risposta != 0) {
/* richiedi un'operazione all'utente */
printf("Che operazione vuoi svolgere?\n");
printf("1 -> Inserisci un triangolo nella lista ordinata secondo il perimetro crescente\n");
printf("2 -> Cancella il triangolo in testa alla lista\n");
printf("3 -> Visualizza la lista di triangoli\n");
printf("0 -> Termina il programma\n");
scanf("%d", &risposta);
/* gestisci le operazioni dell'utente */
if (risposta == 1) {
inserisciPerPerimetro(head);
} else
if (risposta == 2) {
cancellaTriangolo(head);
} else
if (risposta == 3) {
stampaLista(head);
} else
if (risposta == 0) {
printf("Finito!\n\n");
} else {
printf("Selezione non valida!\n\n");
}
}
}
CodePudding user response:
(Sorry for not getting the question right)
Edit:
The change of paramater head in cancellaTriangolo won't apply to the head in main by simply doing head = head->next inside that function.
To solve this issue, code below might help:
void cancellaTriangolo(NODO** head) {
if (*head) {
NODO* p = *head;
*head = (*head)->next;
free(p);
}
}
Call it with cancellaTriangolo(&head).
For other issues like when inserting new node... If you found that new nodes are not being inserted, it might be the same reason. Use NODO** head to send the pointer to head in order to access and change head in functions.
CodePudding user response:
- Your approach of having a head that actually contains no data is wrong and makes your code overly complicated. The first node of a list is by definition the head of the list. If the head is NULL, the list is empty.
- In C parameters are passed by value, so if you want to modify a pointer that has been passed into a function, you need pointers to pointers. The details are explained in this SO question: How do I modify a pointer that has been passed into a function in C?.
You basically want this:
It's not the whole code but only the function that were wrong.
void stampaLista(NODO* head) {
NODO* current = head;
if (current == NULL) {
printf("Lista vuota!\n");
}
else {
while (current != NULL) {
stampaTriangolo(current->t);
current = current->next;
}
}
printf("\n");
}
void inserisciPerPerimetro(NODO** head) {
NODO* nuovo = malloc(sizeof(NODO));
nuovo->t = creaTriangolo();
nuovo->next = NULL;
if (*head == NULL) {
*head = nuovo;
}
else {
if (perimetro(nuovo->t) < perimetro((*head)->t)) {
nuovo->next = *head;
*head = nuovo;
}
else {
while ((*head)->next != NULL && perimetro((*head)->next->t) < perimetro(nuovo->t)) {
*head = (*head)->next;
}
nuovo->next = (*head)->next;
*head->next = nuovo;
}
}
printf("Inserimento effettuato!\n\n");
}
void cancellaTriangolo(NODO** head) {
NODO* primoNodo = NULL;
/* lista vuota? */
if (*head == NULL) {
primoNodo = NULL;
printf("Lista vuota!\n\n");
}
else {
primoNodo = *head;
*head = (*head)->next;
free(primoNodo);
printf("Cancellazione effettuata!\n");
}
}
int main() {
/* inizializza la lista */
NODO* head = NULL;
...
if (risposta == 1) {
inserisciPerPerimetro(&head); // use &head
}
else if (risposta == 2) {
cancellaTriangolo(&head); // use &head
}
...
