Home > Back-end >  Problem in storing data dynamically in linked list
Problem in storing data dynamically in linked list

Time:04-29

I'm trying to write a program that reads a maximum of 8 bank account information and store them dynamically in a linked list. I wrote a function to calculate the average of all the entered bank accounts' balances but when I try to call that function no output is produced. can you please help me figure out where the problem is?

#include <stdio.h>

#include <stdlib.h>

//node structure
typedef struct node {
   int no;
   char name[20];
   float total;
   struct node * nextptr;
}
account;

//int for division of total to find the average
static int t;

//adding accounts function
account * addaccount(account * temp) {
   fflush(stdin);
   printf("Enter the account name: \n");
   gets(temp -> name);
   printf("Enter the account number: \n");
   scanf("%d", & temp -> no);
   printf("Enter the account balance: \n");
   scanf("%f", & temp -> total);
   t  ; // used for finding the average 
   return temp;
}

// function for calculating the average
float sum(account * temp) {
   float average = 1.0, sum = 0.0;
   int i;
   account * start;
   temp = start;
   for (i = 0; i < t; i  ) {
      sum  = temp -> total;
      temp = temp -> nextptr;
   }
   average = sum / t;
   return average;
}

int main() {
   int selection;
   account * start = NULL;
   account * save, * temp;
   account * ptr;
   ptr = (account * ) malloc(sizeof(account) * 8);
   do {
      //Menu
      printf("\n1.Adding account\n");
      printf("2.Find the average of the added accounts' balances\n");
      printf("3.Exit\n");
      scanf("%d", & selection);
      switch (selection) {
      case 1: {
         if (ptr == NULL)
            ptr = (account * ) realloc(ptr, sizeof(account));
         save = addaccount(ptr);
         if (start == NULL) {
            start = save;
            start -> nextptr = NULL;
         } else {
            temp = start;
            while (temp -> nextptr != NULL)
               temp = temp -> nextptr;
            temp -> nextptr = save;
            save -> nextptr = NULL;
         }
         break;
      }
      case 2: {
         float avg;
         avg = sum(temp);
         printf("%f", avg);
         break;
      }
      case 3: {
         temp = start;
         while (temp != NULL) {
            free(temp);
            temp = temp -> nextptr;
         }
         break;
      }
      }
   } while (selection != 4);
   return 0;
}

CodePudding user response:

Look here

// function for calculating the average
float sum(account* temp) {
    float average = 1.0, sum = 0.0;
    int i;
    account* start; <<<==== a random value
    temp = start;   <<<=== over write the parameter of this function with a random value
    for (i = 0; i < t; i  ) {
        sum  = temp->total;
        temp = temp->nextptr;
    }
    average = sum / t;
    return average;
}

Not sure what you are trying to do here - but that is for sure wrong

CodePudding user response:

There are quite a number of problems with your code:

  • you say you want a maximum of 8 accounts, but there is no such limit being imposed by the code.

  • in sum() (which is misnamed, BTW), you are not looping through the nodes correctly, because the temp = start; assignment is backwards. start is uninitialized, and then temp is used inside the loop, thus invoking undefined behavior. You don't actually need the start variable at all, since you can simply increment the account* temp parameter.

  • in main(), you are initially pointing ptr to an array of 8 accounts, but if the user enters 1 on your menu, and ptr is NULL (which it would not be unless that initial malloc() failed), then you are pointing ptr to a single account. If your goal is to allow the user to enter an arbitrary number of accounts, your list management is all wrong.

    Worse, every time the user enters 1 on your menu, you are calling addaccount() on the 1st account in the array, and addaccount() simply populates the specified account with data. So, you are not actually creating a new account and adding it to the list, at all. You are just linking the 1st account back to itself, over and over.

  • if the user enters 2 on your menu, you are calling sum() on the last account created by 1. If no account has been created yet, your code will crash since temp is uninitialized at that point. You need to call the function on the first account instead, so it can iterate the whole list.

  • if the user enters 3 on your menu, the code tries to free() individual accounts, but you did not actually malloc() individual accounts to begin with. You are trying to store accounts in an array instead, so you would just need to free() the array instead.

    Also, your loop is checking for selection != 4, but your menu doesn't have an option 4. You should be checking for selection != 3 instead.

With that said, try something more like this:

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

//node structure
typedef struct node {
   int no;
   char name[20];
   float total;
   struct node * nextptr;
}
account;

//adding accounts function
account* addaccount() {
   account *temp = malloc(sizeof(account));
   if (temp == NULL) {
      printf("Unable to create new account\n");
      return NULL;
   }
   fflush(stdin);
   printf("Enter the account name: \n");
   gets(temp->name);
   printf("Enter the account number: \n");
   scanf("%d", &temp->no);
   printf("Enter the account balance: \n");
   scanf("%f", &temp->total);
   temp->nextptr = NULL;
   return temp;
}

// function for calculating the average
float average(account* start) {
   if (start == NULL) return 0.0;
   float sum = 0.0;
   int t = 0;
   do {
      sum  = start->total;
      start = start->nextptr;
        t;
   }
   while (start != NULL);
   return sum / t;
}

int main() {
   int selection;
   account *start = NULL, *last = NULL, *temp;

   do {
      //Menu
      printf("1.Adding account\n");
      printf("2.Find the average of the added accounts' balances\n");
      printf("3.Exit\n");
      scanf("%d", &selection);
      switch (selection) {
         case 1: {
            if ((temp = addaccount()) == NULL) break;
            if (start == NULL)
               start = temp;
            else
               last->nextptr = temp;
            last = temp;
            break;
         }
         case 2: {
            printf("%f\n", average(start));
            break;
         }
      }
   } while (selection != 3);

   temp = start;
   while (temp != NULL) {
      free(temp);
      temp = temp -> nextptr;
   }

   return 0;
}
  •  Tags:  
  • c
  • Related