So i have a question: i had set up list = ptmp so they should have pointed the same location (NULL in this case) at the very beginning of the function.
This is not quite accurate, you never set list to anything, i.e. it is never on the left side of an assignment (= sign) expression. It's value in the function depends on what you pass in to the function. You do, however, set ptmp to point to list.
Then (after the loop that didn't run in this case because the list was empty) I had set the information in ptmp. Since i had already decleared that ptmp was equal to list, changing ptmp info shouldn't have changed list's as well?
No. You set ptmp to list. ptmp is just a pointer, so all you did was give it the same address as was stored in list. But you overwrote the address in ptmp when you did ptmp = malloc(...). That puts a new address (the one returned by malloc) into ptmp, so now it points somewhere different from list. You are changing different memory from what list points to.
Here is your old code with comments as to what each line was actually doing:
Code:
Invitato *Inserisci_Invitato(Invitato *list){
Invitato *ptmp; // declare ptmp as a pointer to Invitato, it is an uninitialized pointer, pointing to a garbage address
ptmp = list; // now, make ptmp point to the same memory location as list. When list is empty (null), ptmp points to null, otherwise it points to the first element in the list
while (ptmp != NULL){ // this loop only stops when ptmp is NULL. If the list is empty, it never executes. If the list has items, it moves ptmp through the list and
ptmp = ptmp->next; // stops after ptmp has gone past the last node in the list
}
ptmp=(Invitato *)malloc(sizeof(Invitato)); // allocate space for a new node
ptmp->next = NULL; // set the new node's next pointer to NULL
printf("Inserisci Nome: ");
scanf("%s", ptmp->nome); // read in the name
printf("Inserisci Cognome: ");
scanf("%s", &ptmp->cognome); // read in the ?last? name
printf("Partecipazione confermata?(1=si, 0=no 2=forse) ");
scanf("%d", &ptmp->partecipa); // read in the participation
printf("+1? (1=si, 0=no, 2=forse) ");
scanf("%d", &ptmp->uno); // read in the "+1"
printf("\n");
return list; // return list
}
Notice that nowhere in there did you change the value of list. That means that it will never get updated.
Something I forgot to mention in my previous post: you should not cast the return value of malloc. Read this link: FAQ > Casting malloc - Cprogramming.com. A better way to malloc a struct is like this:
Code:
ptmp = malloc(sizeof(*ptmp));
It is preferable to use *ptmp in the sizeof. *ptmp is the thing pointed to by ptmp, i.e. a Invitato object, so sizeof(*ptmp) is equivalent to sizeof(Invitato) here. This way the malloc call will always allocate the right amount of memory. Even if you change the type of the ptmp variable, you need only change the declaration, the malloc call still works.
One more note: as a matter of good program design, a function should do one thing and do it well. The function that inserts a node into your list should not have any user IO in it. A better design would be to have a function called getInvitationInfo(), which allocates an Invitation structure, reads the input from the user and puts it in the allocated structure, then you pass the pointer to that structure to your insert function:
Code:
Invitato *getInvitationInfo(void)
{
Invitato *newNode;
newNode = malloc(sizeof(*newNode));
if (newNode) { // only do this if malloc was successful, to avoid program crashing
print "enter name"
scanf("%s", p->nome);
...
newNode->next = NULL;
}
return newNode;
}
Invitato *insertNode(Invitato *list, Invitato *newNode)
{
Invitato *ptmp;
if (list == NULL) {
list = newNode;
}
else {
walk ptmp to the last node
ptmp->next = newNode;
}
return list;
}
...
// perhaps somewhere in main, or in your menu function
Invitato *newNode;
newNode = getInvitationInfo();
insertNode(list, newNode);
Hope that clears everything up.