An array of structures in c: gives all strings the same values ββ(with int, int works well). What can I do?
When I run the program and assign the values ββid, name, surname, it gives them all the value of the last student. For example, if the last student's name is Anna, then all other array names are Anna. It works well with grades! I tried and didn't use the "constructor" function and had the same thing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student{ /*struct for student info*/
char *id;
char *name;
char *surname;
int grade;
};
struct Student* Student_new(char* id, char* name, char* surname, int grade);
/*fuction: Student 'constructor'*/
int main(int argc, char *argv[]) {
int no; /*number of students*/
printf("Welcome! \n\nNumber of students: ");
scanf("%d", &no);
struct Student *studentArray[no]; /*arary of struct students*/
int i; /*counter*/
for(i=0; i<no; i++){
char id[10], name[10], surname[10];
int grade;
printf("\n\nStudent(%d)\n", i+1);
printf("id: ");
scanf("%s", id);
printf("name: ");
scanf("%s", name);
printf("surname: ");
scanf("%s", surname);
printf("grade: ");
scanf("%d", &grade);
studentArray[i] = Student_new(id, name, surname, grade); /*using Student
'constructor' to initialize the array*/
}
for(i=0; i<no; i++){
printf("%s %s %s %d \n", studentArray[i]->id, studentArray[i]-
>name, studentArray[i]->surname, studentArray[i]->grade);
}
return 0;
}
struct Student* Student_new(char* id, char* name, char* surname, int grade)
{
struct Student* st = malloc(sizeof(struct Student));
st->id = id;
st->name = name;
st->surname = surname;
st->grade = grade;
return st;
}
PLEASE, HELP!
source to share
The problem is that the loop variables go out of scope after each iteration and you are left with dangling pointers in the instances Student
. What you see is the result of undefined behavior .
What is probably happening is that the same char array is passed to every student instance. Then you modify the same char array, overwriting the previous values.
You will need to make copies of the lines. Don't forget to create a function like Student_free
where you free
dynamically allocated copies.
struct Student* Student_new(char* id, char* name, char* surname, int grade)
{
struct Student* st = malloc(sizeof(struct Student));
st->id = strndup(id, 10);
st->name = strndup(name, 10);
st->surname = strndup(surname, 10);
st->grade = grade;
return st;
}
source to share
You must reserve memory for string attributes. As a hint, use a structure similar to:
#define MAX_LEN 32
struct Student{ /*struct for student info*/
char id[MAX_LEN];
char name[MAX_LEN];
char surname[MAX_LEN];
int grade;
};
Determine MAX_LEN
to something sensible for you and make sure the values ββentered are no longer used. Also make sure the strcpy
input values ββfor the structure variables.
source to share
The student structure only contains pointers to char arrays. Now the actual space in memory for strings is allocated in your loop, and its lifetime is limited to the scope of the for loop, after which it is accessed by undefined. In your case, the space in which the strings have not been reused and redefined, so you might accidentally keep the last value (such cases can also cause a segmentation fault).
You should take a look at some basic tutorial on pointers and memory models c. Allocating arrays in a structure is a good solution ( nucleon answer ). Also, the scanf function can overflow, you should limit the number of characters received according to the size of the allocated array.
source to share