I'm trying to push an element in a linked list, then print it but the problem received is: segmentation fault.
I've created struct libro, cella and lista. Then in function insHead i've tried to insert an element to the list, taking input from user and then in function printList (and here i've got the segmentation fault) i would print list's elements.
The code is:
typedef struct libro {
char titolo[64];
char autore[32];
short inLibreria;
short fuoriLibreria;
short id;
} Libro;
typedef struct cella {
Libro libro;
struct cella *pNext;
} Cella;
typedef Cella *Pcella;
typedef struct listaLibri{
Cella *pFirst;
Cella *pLast;
} ListaLibri;
void insHead(ListaLibri lista){
Pcella cella;
Libro libro;
printf("Inserisci titolo libro: ");
scanf("%s", libro.titolo);
printf("Inserisci autore libro: ");
scanf("%s", libro.autore);
printf("Inserisci il numero di copie presenti in libreria: ");
scanf("%d",&libro.inLibreria);
if(lista.pFirst == NULL){
cella = NULL;
Pcella temp = cella;
cella = malloc(sizeof(Cella));
(*cella).libro = libro;
(*cella).pNext = temp;
lista.pFirst = cella;
lista.pLast = cella;
}
printList(lista);
}
void printList(ListaLibri *lista){
Pcella cella = lista->pFirst;
Pcella temp = cella;
while (temp != NULL){
printf("%s", temp->libro.autore);
temp = temp->pNext;
}
free(cella);
free(temp);
}
void main(){
ListaLibri lista;
insHead(lista);
}
First of all you have to initialize lista.pFirst and lista.pLast with NULL.
int main()
{
ListaLibri lista;
lista.pFirst = NULL; // <- init NULL
lista.pLast = NULL; // <- init NULL
insHead( &lista ); // <- pass pointer to list to function insHead
insHead( &lista );
.....
deleteList( &lista );
return 0;
}
The input paramter to your function insHead has to be an in and output paramter. Otherwise you would pass an copy of lista to function insHead and never get back its content.
void insHead( ListaLibri *lista )
// ^ input and outout paramter
{
if ( lista == NULL )
return;
Cella *head = lista->pFirst; // remember head of list
lista->pFirst = malloc(sizeof(Cella)); // allocate new node right to target
lista->pFirst->pNext = head; // successor of new node is head of list
if ( lista->pLast == NULL ) // if list was empty new node is tail of list
lista->pLast = lista->pFirst;
Libro libro;
printf("Inserisci titolo libro: ");
scanf("%s", libro.titolo);
printf("Inserisci autore libro: ");
scanf("%s", libro.autore);
printf("Inserisci il numero di copie presenti in libreria: ");
scanf("%d",&libro.inLibreria);
lista->pFirst->libro = libro;
printList( lista );
}
Don't delete nodes infunction print.
void printList(ListaLibri *lista)
{
if ( lista == NULL )
return;
Pcella temp = lista->pFirst;
while (temp != NULL)
{
printf("%s\n", temp->libro.autore);
temp = temp->pNext;
}
}
Write a function which deletes the list.
void deleteList(ListaLibri *lista)
{
if ( lista == NULL )
return;
Pcella temp = lista->pFirst;
while (temp != NULL) // terminate if tail of list is reached
{
Pcella next = temp->pNext; // rmember successor of node
free( temp ); // delete node
temp = next; // go to next node
}
lista->pFirst = NULL;
lista->pLast = NULL;
}
You are not assigning the pFirst value, so it is having garbage data, which is not equal to NULL.
Modify your code like this;
void insHead(ListaLibri lista)
{
// Your code goes here
lista.pFirst = NULL;
if(lista.pFirst == NULL)
{
// Your code goes here
}
printList(&lista); //Pass it as a reference, because printList() input parameter is a pointer type.
}
Hope this helps.
You declare lista in main, but you don't initialize any fields. My guess is that lista.pFirst is non-NULL garbage and you if is then skipped.
Related
Hi I'm trying to insert an element inside a list following a certain order(I have to add a equilateral triangle). When I try to use the code I can insert data(triangle measurements) but when I try to print list nothing appear :/.So I think that I wrote bad something in "inserisciPerPerimetro". Some word is written in italian and this is only a part of the code(two functions to add a triangle in my list),if u have to see also other parts let me know.
Thanks all!
This is my code:
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;
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);
}
}
}
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* nuovoNodo;
nuovoNodo = malloc(sizeof(NODO));
nuovoNodo->t = creaTriangolo();
nuovoNodo->next = NULL;
if(head==NULL) {
head = nuovoNodo;
} else {
//Ordinamento per perimetro crescente
while(head->next != NULL)
if(perimetro(nuovoNodo->t) < perimetro(head->t)) {
nuovoNodo->next = head->next;
head->next = nuovoNodo;
} else {
head = head->next;
}
printf("Inserimento effettuato!\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)
//lista = cancellazione(lista);
else if(risposta==3) {
stampaLista(head);
}
else if(risposta==0) {
printf("Finito!\n\n");
}
else {
printf("Selezione non valida!\n\n");
}
}
}
I'm going to assume that you're holding a NODO* in some outer scope, and calling inserisciPerPerimetro on that pointer.
If you consider just the first time you do this (when the list is empty), your code will do head = nuovoNodo; so you will be putting the address of the newly allocated node into the pointer head. But this is a local copy of the parameter that you passed to the function, so the pointer in the outer scope will remain unchanged (and its value will be NULL). The next time you call the function, the list will still be empty.
One possible way to solve this is by passing a pointer to your head pointer to the function, so that the value of the pointer in the outer scope can be modified.
That is, the function should be defined like this:
void inserisciPerPerimetro(NODO **head)
Inside the function, modifications to head should be implemented as:
*head = nuovoNodo;
And in the outer scope you should have something like:
/*...*/
NODO* head = NULL;
inserisciPerPerimetro(&head);
/*...*/
EDIT:
Note that you are somewhat inconsistent with the node allocations: The head node is allocated in the outer scope (does it ever get its own triangle?), and all the others are allocated within the function. On the other hand, you check inside the function whether head is NULL - how can that happen if you allocate the list head in the outer scope?
Secondly, note that in the first call to inserisciPerPerimetro the while loop will be skipped because head->next is always NULL. This is because you don't handle the case where the new node needs to be inserted after the last node in the list.
im having a problem, im trying to make a list of a list where inicioC refers to the first node of clients, and every node of clients will have a list of rentals, referred as inicioA. The thing is, i dont know how to save the first pointer of the rentals, like, the first node of clients will only be saved one time, but wont the first node of every rental be different?
this are the structs:
typedef struct _aluguer
{
int id, estado, diaI, mesI, anoI, diaE, mesE, anoE;
struct _aluguer *prox;
}aluguer, *pAluguer;
typedef struct _registo
{
int nif,nalu;
char nome[100];
struct _registo *prox;
pAluguer *inicioA;
}registo, *pRegisto;
and this is the code I use to extract the info from a file into the list of lists
pRegisto iniC(pRegisto inicioC, pAluguer inicioA)
{
FILE *c;
int j, nif, nalu, l=0;
char nome[100];
c = fopen("clientes.txt", "r"); // abrir ficheiro
if(c == NULL)
{
printf("Erro ao abrir ficheiro %s", "clientes.txt");
exit(0);
}
while(fscanf(c, "%d %d %s", &nif, &nalu, nome) == 3) //format of info
{
pRegisto novoC = malloc(sizeof(registo));
if(novoC == NULL)
{
printf("erro alocacao memoria\n");
return inicioC;
}
novoC -> prox = NULL;
pAluguer inicioA = NULL;
pRegisto aux = inicioC;
pRegisto p = NULL;
novoC->nif=nif;
novoC->nalu=nalu;
strcpy(novoC->nome, nome);
while(aux != NULL)
{
p = aux;
aux = aux->prox;
}
if( aux == inicioC)
{
inicioC=novoC;
}
else
{
p->prox = novoC;
}
for(j=0; j<novoC->nalu; j++) // repeat is equal to the number of rentals
{
l++;
pAluguer novoA = malloc(sizeof(aluguer));
if(novoA == NULL)
{
printf("erro alocacao memoria\n");
return inicioC;
}
novoA -> prox = NULL;
pAluguer aux = inicioA;
pAluguer p = NULL;
fscanf(c, "%d %d", &(novoA->id), &(novoA->estado));
if(novoA->estado == 0)
{
fscanf(c, " %d %d %d", &(novoA->diaI), &(novoA->mesI), &(novoA->anoI));
}
else
{
fscanf(c, " %d %d %d %d %d %d", &(novoA->diaI), &(novoA->mesI), &(novoA->anoI), &(novoA->diaE), &(novoA->mesE), &(novoA->anoE));
}
while(aux != NULL)
{
p = aux;
aux = aux->prox;
}
if( aux == inicioA)
{
inicioA=novoA;
}
else
{
p->prox = novoA;
}
}
}
fclose(c);
return inicioC;
}
Arraylist (Array of pointers in C) is good choice for implementing list of list but as you are forced to do in this way, I am showing a Simple method how you can develop list of list in C.
It is very simple,suppose you have a list of 3 numbers: 1,2,3 i.e list_1,list of 2 numbers: 5,6 i.e list_2.Now these list_1 and list_2 can be linked in a similar way as the numbers in list linked above.Look at this scenario
list_1:1->2->3->Null
list_2:5->6->Null
list_of_list : list_1->list_2->Null i.e. (1->2->3->Null) -> (5->6->Null) -> Null
Here is a Sample program to insert list of ints in Last:
#include <stdio.h>
#include <stdlib.h>
// for list of Intergers
struct node{
int Data;
struct node *next;
};
// this is for list of nodes i.e list of lists
struct list{
struct node *start;
struct list *listnext;
};
// insert integers in list
void insertNode(struct node **head ,int data){
struct node *temp,*current;
temp=malloc(sizeof(struct node));
temp->Data=data;
temp->next=NULL;
if((*head)==NULL){
(*head)=temp;
}
else{
current=(*head);
while(current->next!=NULL){
current=current->next;
}
current->next=temp;
}
}
// insert lists of integers in a list
void insertList(struct list **Listhead,struct node *head){
struct list *temp,*current;
temp=malloc(sizeof(struct list));
temp->start=head;
temp->listnext=NULL;
if((*Listhead)==NULL){
(*Listhead)=temp;
}
else{
current=(*Listhead);
while(current->listnext!=NULL){
current=current->listnext;
}
current->listnext=temp;
}
}
// Show all the list with their data
void show(struct list *Listhead){
int i=1;
struct list *current;
struct node *currentlist;
current=Listhead;
while(current!=NULL){
currentlist=current->start;
printf("List %d: ",i);
while(currentlist!=NULL){
printf("%d ",currentlist->Data);
currentlist=currentlist->next;
}
i++;
printf("\n");
current=current->listnext;
}
}
int main(){
struct node *head1=NULL,*head2=NULL,*head3=NULL; // 3 lists of integers
struct list *Listhead=NULL; // Listhead will be the head of lists of list
insertNode(&head1,20); // inserting in first list
insertNode(&head1,13);
insertNode(&head1,22);
insertNode(&head1,18);
insertNode(&head2,42); // inserting in second list
insertNode(&head2,15);
insertNode(&head3,12); // inserting in third list
insertNode(&head3,14);
insertNode(&head3,28);
insertList(&Listhead,head1); // inserting lists in list
insertList(&Listhead,head2);
insertList(&Listhead,head3);
show(Listhead);
}
Output for this Program:
List 1: 20 13 22 18
List 2: 42 15
List 3: 12 14 28
I hope you got the point.
I'm writing a function that places new nodes alphabetically into a linked list structure by sorting them by the name field. Here is my program, intended to test that it can successfully insert a new node into an existing structure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 100
#define MAX_JOB_LENGTH 100
struct Employee
{
/* Employee details */
char name[MAX_NAME_LENGTH+1]; /* name string */
char sex; /* sex identifier, either ’M’ or ’F’ */
int age; /* age */
char job[MAX_JOB_LENGTH+1]; /* job string */
/* pointers to previous and next employee structures in the linked list
(for if you use a linked list instead of an array) */
struct Employee *prev, *next;
};
void place_alpha(struct Employee *new, struct Employee **root);
int main(){
struct Employee *a;
struct Employee *c;
struct Employee *b;
a = malloc(sizeof(struct Employee));
c = malloc(sizeof(struct Employee));
b = malloc(sizeof(struct Employee));
strcpy(a->name, "A");
a->sex = 'F';
a->age = 42;
strcpy(a->job, "Optician");
a->prev = NULL;
a->next = c;
strcpy(c->name, "C");
c->sex = 'F';
c->age = 22;
strcpy(c->job, "Nurse");
c->prev = a;
c->next = NULL;
strcpy(b->name, "B");
b->sex = 'M';
b->age = 34;
strcpy(b->job, "Rockstar");
b->prev = NULL;
b->next = NULL;
place_alpha(b, &a);
if(a->prev == NULL)
{
printf("a->prev is correct\n");
}else{
printf("a->prev is INCORRECT\n");
}
if(a->next == b)
{
printf("a->next is correct\n");
}else{
printf("a->next is INCORRECT");
}
if(b->prev == a)
{
printf("b->prev is correct\n");
}else{
printf("b->prev is INCORRECT\n");
}
if(b->next == c)
{
printf("b->next is correct\n");
}else{
printf("b->next is INCORRECT\n");
}
if(c->prev == b)
{
printf("c->prev is correct\n");
}else{
printf("c->prev is INCORRECT\n");
}
if(c->next == NULL)
{
printf("c->next is correct\n");
}else{
printf("c->next is INCORRECT\n");
}
}
void place_alpha(struct Employee *new, struct Employee **root) //Places a new node new into the database structure whose root is root.
{
if(*root==NULL) //If there is no database yet.
{
*root = new;
(*root)->prev = NULL;
(*root)->next = NULL;
}
else
{
if(strcmp(new->name, (*root)->name)<=0) // if the new node comes before root alphabetically
{
new->next = *root;
new->prev = (*root)->prev;
if((*root)->prev != NULL)
{
(*root)->prev->next = new;
}
(*root)->prev = new;
*root = new;
return;
}
else if((*root)->next == NULL) // If the next node is NULL (we've reached the end of the database so new has to go here.
{
new->prev = *root;
new->next = NULL;
(*root)->next = new;
return;
}
else if(strcmp(new->name, (*root)->name)>0) // If the new node comes after root alphabetically
{
place_alpha(new, &(*root)->next);
return;
}
}
}
Sadly, the program is unsuccessful, as showcased by the output:
a->prev is correct
a->next is correct
b->prev is INCORRECT
b->next is correct
c->prev is INCORRECT
c->next is correct
Program ended with exit code: 0
I can't figure out why, as I've clearly set b->next to c and c->prev to b.
This was tricky: there is a subtile bug in your place_alpha() function: you update *root even if it is not the root node of the list. This causes the pointer b to be updated erroneously. place_alpha() should only be called with a pointer to the actual root node.
I modified your code to make it more readable and reliable:
I wrote a function to create a new node
I protected the string copies from overflow using calloc() and strncat(). Read about these functions in the manual.
I use place_alpha() to insert all 3 nodes into the list in the same order you do.
I use newp instead of new to avoid C++ keywords in C code.
Note that place_alpha() must be called with a pointer to the head pointer of the list, if you pass a pointer to an intermediary node, chaining back along the prev links would locate the first node, but if the new employee should be inserted at the head of the list, you would not have the address of the root node to update in the caller's scope. This is the reason many programmers prefer to use a specific structure for the list head.
Here is the updated code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 100
#define MAX_JOB_LENGTH 100
struct Employee {
/* Employee details */
char name[MAX_NAME_LENGTH + 1]; /* name string */
char sex; /* sex identifier, either 'M' or 'F' */
int age; /* age */
char job[MAX_JOB_LENGTH + 1]; /* job string */
/* pointers to previous and next employee structures in the linked list
(for if you use a linked list instead of an array) */
struct Employee *prev, *next;
};
void place_alpha(struct Employee *new, struct Employee **root);
struct Employee *new_employee(const char *name, char sex, int age, const char *job) {
struct Employee *newp = calloc(1, sizeof(*newp));
if (!newp) {
fprintf(stderr, "cannot allocate employee\n");
exit(1);
}
strncat(newp->name, name, MAX_NAME_LENGTH);
newp->sex = sex;
newp->age = age;
strncat(newp->job, job, MAX_JOB_LENGTH);
newp->next = newp->prev = NULL;
return newp;
}
int main(void) {
struct Employee *list = NULL;
struct Employee *a = new_employee("A", 'F', 42, "Optician");
struct Employee *b = new_employee("B", 'M', 34, "Rockstar");
struct Employee *c = new_employee("C", 'F', 22, "Nurse");
place_alpha(a, &list);
place_alpha(c, &list);
place_alpha(b, &list);
if (a->prev == NULL) {
printf("a->prev is correct\n");
} else {
printf("a->prev is INCORRECT\n");
}
if (a->next == b) {
printf("a->next is correct\n");
} else {
printf("a->next is INCORRECT");
}
if (b->prev == a) {
printf("b->prev is correct\n");
} else {
printf("b->prev is INCORRECT\n");
}
if (b->next == c) {
printf("b->next is correct\n");
} else {
printf("b->next is INCORRECT\n");
}
if (c->prev == b) {
printf("c->prev is correct\n");
} else {
printf("c->prev is INCORRECT\n");
}
if (c->next == NULL) {
printf("c->next is correct\n");
} else {
printf("c->next is INCORRECT\n");
}
return 0;
}
void place_alpha(struct Employee *newp, struct Employee **root) {
// Insert a new node newp into the database structure whose root is root.
struct Employee *ep;
if (*root == NULL) { // if there is no database yet.
newp->next = newp->prev = NULL;
*root = newp;
return;
}
if ((*root)->prev) {
// invalid call, should only pass the root node address
fprintf(stderr, "invalid call: place_alpha must take a pointer to the root node\n");
return;
}
if (strcmp(newp->name, (*root)->name) <= 0) {
// if the new node comes before root alphabetically
newp->next = *root;
newp->prev = NULL;
newp->next->prev = newp;
*root = newp;
return;
}
for (ep = *root;; ep = ep->next) {
if (ep->next == NULL) {
// If the next node is NULL, we've reached the end of the list
// so newp has to go here.
newp->prev = ep;
newp->next = NULL;
newp->prev->next = newp;
return;
}
if (strcmp(newp->name, ep->next->name) <= 0) {
// The new node comes between ep and ep->next alphabetically
newp->prev = ep;
newp->next = ep->next;
newp->prev->next = newp->next->prev = newp;
return;
}
}
}
EDIT: place_alpha was a bit redundant, so I cleaned it and got a much simpler version:
void place_alpha(struct Employee *newp, struct Employee **root) {
//Places a new node newp into the database structure whose root is root.
struct Employee **link = root;
struct Employee *last = NULL;
while (*link && strcmp(newp->name, (*link)->name) > 0) {
last = *link;
link = &last->next;
}
newp->prev = last;
newp->next = *link;
if (newp->next) {
newp->next->prev = newp;
}
*link = newp;
}
Hello guys i got a problem while running this code:
trying to run the printf in the comment i got a segfault, also without that i dont see my listed printed ad the function Stampa should do.
Probably i am missing something with pointers
#include <stdio.h>
#include <stdlib.h>
struct nodo { // double linked list
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
// printf("%d",p->succ->info);
Stampa(p);
return 0;
}
// this funct should print the whole list
void Stampa (struct nodo *p) {
while (p->succ != NULL ) {
printf("Value : %d \n", p->info);
p = p->succ;
}
}
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
Stampa()
Let's look at what we want to do when we print the entire list:
If the current element is valid, then we want to print it.
Then, we want to iterate to the next element, and continue this loop.
That's not what your code does. Your code looks to see if the current element has a successor, and if it does, we print the current element's value.
That function should actually be:
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d\n", p->info);
p = p->succ;
}
}
Crealista()
If you tell Crealista() to create a list of 0 elements, your final while loop will exhibit undefined behavior.
If you tell Crealista() to create a list of less than 2 elements, your commented printf() in main() will cause undefined behavior (if it was uncommented).
Doubly Linked Lists
You never update the value of nodo->succ. You only update the value of nodo->prev. Here's one example of how to do that:
if (p->prec)
p->prec->succ = p;
Putting all of this together
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
Stampa(p);
}
// Print the list
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d \n", p->info);
p = p->succ;
}
}
// Create a list of n elements
struct nodo *Crealista(void) {
int i, n;
struct nodo *p = NULL;
struct nodo *primo = NULL;
struct nodo *back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
assert(n != 0);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
if (p->prec)
p->prec->succ = p;
back = p;
}
primo = p;
while (primo != NULL && primo->prec != NULL)
primo = primo->prec;
return primo;
}
Which when run...
Numero di elementi: 5
inserisci 5 numeri interi positivi: 1 2 3 4 5
Value: 1
Value: 2
Value: 3
Value: 4
Value: 5
The printf() call you have commented out will always exhibit undefined behavior when p->succ is NULL, as it will be when p points to the last (or only) element of the list. In that case, although the behavior is formally "undefined", it is quite likely to manifest as a segmentation fault.
In stampa add check
while(p!=NULL)
{
printf("Value %d",p->info);
p=p->succ;
}
You are probably accessing it when it is not allocated. Check it this way there is no problem if it reaches a null value also. And initial null value will not cause problem also(if used).
I have modified your code
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
for (i=1; i<n; i++) {
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->prec->succ=p;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
You are not setting the succ pointer of previous node correctly. That is what causing you the problem. Check now.
How can I change the pointer named "* FIRST" that points on the first element of a linked list if I want to delete it's first element?
-my problem is that when I delete the first node, the pointer point in the seconde node.But when I display the adress of the element I pointed on, I found that FIRST=NULL.
Thank you in advance.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{int note;
struct personne *next;
}personne;
personne *first=NULL;
void saisi (personne *first,int mark)
{ personne *nouveau=malloc(sizeof(personne));
nouveau->note=mark;
nouveau->next=NULL;
if(first==NULL)
first=nouveau; // here is the problem
else
{ personne *tmp;
tmp=first;
while (tmp->next!=NULL) tmp=tmp->next;
tmp->next=nouveau;
}
}
void affichage (personne *first)
{int i=1;
personne *tmp;
tmp=first;
do
{printf("la note %d : %d \n",i,tmp->note);
i++;tmp=tmp->next;
}while (tmp!=NULL);
}
void suppresion (personne *first,int n)
{personne *tmp1=NULL,*tmp2=NULL;
tmp1=first;
while (tmp1 != NULL)
{ if ((tmp1->note) >n){
tmp2->next=tmp1->next;
}
tmp2=tmp1;
tmp1=tmp1->next;
}
}
int main()
{
int N=1,mark=0,n=0;
while (N!=4)
{ printf ("donner la note %d:",N);
scanf ("%d",&mark);
saisi (first,mark);
N++;
}
affichage (first);
printf("donner n :");
scanf("%d",&n);
suppresion (first,n);
affichage(first);
return 0;
}
As commented by dasblinkenlight, use a pointer to pointer:
void saisi (personne **ppfirst, int mark)
{
personne **ppnode = ppfirst;
personne *nouveau=malloc(sizeof(personne));
nouveau->note=mark;
nouveau->next=NULL;
while(*ppnode != NULL)
ppnode = &((*ppnode)->next);
*ppnode = nouveau;
}
void suppresion (personne **ppfirst, int n)
{
personne **ppnode = ppfirst;
personne *pnode;
while (*ppnode != NULL)
{
if((*ppnode)->note > n){
pnode = *ppnode;
*ppnode = (*ppnode)->next;
free(pnode);
} else {
ppnode = &((*ppnode)->next);
}
}
}
/* ... */
saisi(&first, mark);
/* ... */
suppresion(&first, n);
1.- Since "first" is a global variable, you don't need to pass it as argument at each function call.
2.- At the "suppresion" method, "temp2" could be pointing to NULL when you try to call "temp2->next".
3.- You must free memory when deleting an element of your list.
4.- I don't understand well what are you asking, but if you want to delete many elements of your linked list, here is the way i would make the supression method, supposing that the method deletes all the nodes with a (mark > n):
void suppresion (int n)
{
personne *tmp1=NULL,*tmp2=NULL;
tmp1=first;
//First check all elements except the first one
while (tmp1 != NULL)
{
if ((tmp1->next != NULL)&&(tmp1->next->note >n))
{
tmp2=tmp1->next;
tmp1->next = tmp2->next;
free(tmp2);
}
else
{
tmp1=tmp1->next;
}
}
//Now go for the first element
if(first != NULL && first->note > n)
{
tmp1 = first;
first = tmp1->next;
free(tmp1);
}
}
That method searches all the elements of the array and delete all the elements that have a mark > n in just one method call; normally you create a method that deletes a concrete element and call it from a loop in another section of your code.