1
votes

I am trying to create a linked list which stores name and age of a student. I am having trouble with insertion.

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

typedef struct node{

  char Name[50];
  int studentAge;
  struct node* next;

}MyNode;

this is how i defined my Struct which constains the requried data and a pointer 'next' which points to the next node.

Below is my insertion function so in the first if condition i am saying if there isnt a head ie head = NULL then create memory space for the head using malloc.. after this i copy all the data into the head node and making sure that the next of head points to null.

In the second condition i am saying if there is a head ie Head ! = NULL then traverse the list to the end using the current pointer and then copy all the data in.

void InsertStudent(char givenName[50], int age, MyNode* head){

    if(head == NULL){
        head = (MyNode*) malloc(sizeof(MyNode));
        strcpy(head->Name,givenName);
        head->studentAge = age;
        head->next = NULL;
    }


    if(head != NULL){
        MyNode* current = head;
            while(current->next != NULL){
                current = current->next;
            }
        current->next = (MyNode*) malloc(sizeof(MyNode));
        strcpy(current->next->Name,givenName);
        current->next->studentAge = age;
        current->next->next = NULL;
    }

}

Now i am not sure if there is a problem in my printing or inserting because it doesn't print my nodes when i try the code out

void PrintList(MyNode* head){
    MyNode* current = head;

    while(current != NULL){
        printf("Name is %s Age is %d\n",current->Name,current->studentAge);
        current = current->next;
    }

}

this is my main function.. is there a problem with the MyNode* head = NULL; line of code is that allowed?

  int main()
   {


    MyNode* head = NULL;

    int r = 0;
while(r!=1)
    {
    printf("Data Structures - Linked List\n");
    printf("Choose one Option:\n\n");
    printf("1.Insert Student\n");
    printf("2.Remove Student\n");
    printf("3.Print all student\n");
    printf("4.Exit\n");

        int option=0;
        char givenName[50];
        int givenAge;
        scanf("%d",&option);

        switch(option){

        case 1:
        printf("Enter name of student:     ");
        scanf("%s",givenName);
        printf("\nEnter Age of student:    ");
        scanf("%d",&givenAge);
        InsertStudent(givenName,givenAge,head);
            break;

        case 2:
        printf("Enter name of student:     ");
        scanf("%s",givenName);
        printf("\nEnter Age of student:    ");
        scanf("%d",&givenAge);
        RemoveStudent(givenName,givenAge);
            break;

        case 3:
        PrintList(head);
            break;
        case 4:
        r=1;
            break;
        default:
        r=1;
        printf("\nNot an option\n");
            break;

       }

    }
}
2
head = (MyNode*) malloc(sizeof(MyNode)) in InsertStudent means nothing to the caller of that function. The head pointer is passed by value. Assigning to it as such just modifies a local variable; the caller's pointer remains unchanged. Either utilize the otherwise-unused return value of the function to communicate a possibly-updated head pointer, or pass the head pointer by address (so a pointer-to-pointer) and change the code in InsertStudent accordingly. There are at least a thousand duplicates of this problem on SO. I'll try and hunt one down.WhozCraig
Found one here. The first and second answers actually demonstrate both methods I described above.WhozCraig
from what i have seen, are you trying to suggesting to either change void Insert(..) to MyNode* insert(...) and return the new node... or the second method is to use void ( double pointer)... is that what your saying? i would like to go with double pointers as that seems harder but i don't really know how to do it..EEECS
The comment I posted, in conjunction with the answer and prior question I linked, cannot possibly describe better what needs to be done. The second answer in the linked question shows precisely how to do this with pointer-to-pointer syntax.WhozCraig
thanks. ill fix it now. i just saw ur second post so i didnt know you linked an exampleEEECS

2 Answers

0
votes

You're not setting the initial value of the head pointer to the first node, and since that is never done, the list remains empty and you leak memory like a sieve leaks rain water.

As you have communicated you want to use pointer-to-pointer syntax, the result should look like this . (sans error checking, which you shoudl probably consider adding):

void InsertStudent(char givenName[50], int age, MyNode** head)
{
    while (*head)
        head = &(*head)->next;

    *head = malloc(sizeof **head);
    strcpy((*head)->Name, givenName);
    (*head)->studentAge = age;
    (*head)->next = NULL;
}

Invoked from your main program using the address of the head pointer (do NOT confused that with the address held in the head pointer which you're initially setting to NULL correctly; think of the latter a value held by a pointer, the former as a residence where the head pointer itself is in memory).

InsertStudent(givenName,givenAge, &head); // NOTE THIS

I leave the task of removal and list cleanup.

0
votes

You are passing head by value; which means that the line in InsertStudent:

head = (MyNode*) malloc(sizeof(MyNode))

which does not update the variable ‘head’ in main. What you want is to pass &head to InsertStudent, but then InsertStudent has to deal with a MyNode **. The other option is have InsertStudent return head, so that its invocation is:

 head = InsertStudent(name, age, head);

It doesn’t matter much either way, some people prefer the latter because it looks more functional.

Inside of InsertStudent, you add the first element twice. This is almost certainly unwanted. By the time you get to the line:

if(head != NULL){

head is never NULL; if it were, you would have assigned it in the if statement above. You probably want this statement to be:

else {