c - Returning array address from function did not work -


i have c program in user enters sets of grades. works correctly. gpa calculated correctly, etc. however, when numbers printed out, both pointers in student structs point same address reason, leading both students display grades of second when information printed out. rest of information correct, it's grades identical.

the thing can think of second initialization of grades array overwrites first. don't understand why happens or how fix it.

the following sample io of program:

enter number of students:> 2 enter number of grades track:> 3  there 2 students. there 3 grades.  enter information student:         enter sid:> 101         enter last name:> enright         enter first name:> reed         enter grades (separated space):> 70.1 60 92  enter information student:         enter sid:> 123         enter last name:> claire         enter first name:> heidi         enter grades (separated space):> 82.5 96.1 89.0  student id #101:         name:   reed enright         grades: 82.5 96.1 89.0         gpa:    74.03 student id #123:         name:   heidi claire         grades: 82.5 96.1 89.0         gpa:    89.20 

and complete code:

#include <stdio.h> #define name_size 25  typedef struct {         int sid;         char last_name[name_size];         char first_name[name_size];         float *grades;         float gpa; } student;  // function prototypes  // student information student prompt_student(int number_of_grades);  // calculate gpa based on grades float calculate_gpa(student student, int number_of_grades);  // prints of students void print_all_students(student students[], int number_of_students, int number_of_grades);  int main(){         // initialise variables         int number_of_students;         int number_of_grades;          // prompt number of students         printf("\nenter number of students:> ");         scanf("%d", &number_of_students);         // prompt number of grades         printf("enter number of grades track:> ");         scanf("%d", &number_of_grades);          // confirm above         printf("\nthere %d students. \nthere %d grades.\n",                         number_of_students, number_of_grades);          // initialise student list         student students[number_of_students];         // , store student information         for(int = 0; < number_of_students; i++){                 students[i] = prompt_student(number_of_grades);         }          // confirm above         print_all_students(students, number_of_students, number_of_grades);          return 0; }  student prompt_student(int number_of_grades){         // initialise student variable         student student;         float grades[number_of_grades];         printf("\nenter information student: \n");          // prompt student info         printf("\tenter sid:> ");         scanf("%d", &(student.sid));          printf("\tenter last name:> ");         scanf("%s", student.last_name);          printf("\tenter first name:> ");         scanf("%s", student.first_name);          printf("\tenter grades (separated space):> ");         for(int = 0; < number_of_grades; i++){                 scanf("%f", &grades[i]);         }         student.grades = grades;          student.gpa = calculate_gpa(student, number_of_grades);          return student; }  float calculate_gpa(student student, int number_of_grades){         float total = 0; // initialise variable sum of grades         // add grades         for(int = 0; < number_of_grades; i++){                 total += student.grades[i];         }         // return average         return total / number_of_grades; }  void print_all_students(student students[], int number_of_students, int number_of_grades){         // loop through students         for(int = 0; < number_of_students; i++){                 // print student info                 printf("\nstudent id #%d:", students[i].sid);                 printf("\n\tname:\t%s %s", students[i].first_name, students[i].last_name);                 printf("\n\tgrades:\t");                 for(int n = 0; n < number_of_grades; n++){                         printf("%.1f ", students[i].grades[n]);                 }                 printf("\n\tgpa:\t%.2f", students[i].gpa);         }         printf("\n"); } 

the problem inside function prompt_student declared local array

float grades[number_of_grades]; 

and address of first element of local array assigned data member grades of structure student

student.grades = grades; 

so data member have same address each call of function. , program has undefined behaviour because after exiting function local array not alive. in general case destroyed.

you must dynamically allocate array , assign address of allocated array data member grades.

for example

float *grades = malloc( number_of_grades * sizeof( float ) ); 

it obvious in main should free allocated memory when corresponding object of structure not used more.


Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -