The part that is bothering me is the last for loop which I used just to test whether the data is entered correctly and that it is printed using printf properly. The three access methods used to print the data which I entered aren't quite clear to me.
In access method #1 I managed to print data properly using only one arrow operator to access name. The part I can't wrap my head around is why am I able to access the data without an error? I only used index to access each production_plant_employees structure. I know the brackets do the dereferencing, but I still don't understand what's happening there. I tried writing that part like this : *(production_plant_employees + i), but it didn't work.
Access method #2 is fully clear to me.
Now the access method #3, that's the one I assumed would work, but it refuses to. When written, IDE shows no errors, but when I run the program, it stops.
I am supposed to first access data in first pointer (which is production_plant_employees), and then then access data in second pointer (which is pointer basic_info which is in struct employee), and then, when I've gone through the 2 pointers, access the very data I am after (name, age, etc...), right?
Also, could you please show me any other possible ways of accessing the data I'm after?
typedef struct basicdata{
char name[15];
char last_name[15];
char gender[2];
int age;
char birthplace[15];
char address[15];
} BASICDATA;
typedef struct job_info {
int employment_year;
char job_position[20];
char employee_pay_grade[10];
int employee_grade;
} JOB_INFO;
typedef struct employee{
BASICDATA *basic_info;
JOB_INFO *job_info;
} EMPLOYEE;
int main () {
int i;
int choice = 0;
EMPLOYEE *production_plant_employees;
printf("Enter number of employees : \n");
scanf("%d", &choice);
production_plant_employees = (EMPLOYEE*)calloc(choice, sizeof(EMPLOYEE));
if (production_plant_employees == NULL) {
printf("An error occured during memory allocation\n");
}
for(i = 0; i < choice; ++i) {
production_plant_employees[i].basic_info = (BASICDATA*)calloc(choice, sizeof(BASICDATA));
if(production_plant_employees[i].basic_info == NULL) {
printf("An error occured during memory allocation\n");
}
production_plant_employees[i].job_info = (JOB_INFO*)calloc(choice, sizeof(JOB_INFO));
if(production_plant_employees[i].job_info == NULL) {
printf("An error occured during memory allocation\n");
}
printf("production_plant_employees[%d].basic_info = %d\t%x\n", i, production_plant_employees[i].basic_info, production_plant_employees[i].basic_info);
printf("production_plant_employees[%d].job_info = %d\t%x\n", i, production_plant_employees[i].job_info, production_plant_employees[i].job_info);
}
for(i = 0; i < choice; ++i) {
fflush(stdin);
printf("Enter name : \n");
fgets(production_plant_employees[i].basic_info->name, 15, stdin);
printf("Name of %d. employee : %s", i, production_plant_employees[i].basic_info->name) //access method#1
printf("Name of %d. employee : %s", i, (production_plant_employees + i)->basic_info->name); //access method #2
printf("Name of %d. employee : %s", i, *(*(production_plant_employees +i)).basic_info->name); //access method #3 ---> why isn't this working?
printf("\n\n");
}
return 0;
}
1 Answer 1
The right way to do it is (for access method 3):
printf("Name of %d. employee : %s", i, (*(*(production_plant_employees +i)).basic_info).name);
First we start by dereferencing pointer production_plant_employees +i, now, we access member basic_info which is also a pointer & needs to get dereferenced using the second * to access local member name.
ptr1 = production_plant_employees +i
ptr2 = (*ptr1).basic_info
data = (*ptr2).name
And thus (substituting ptr2 in data:
data = (*(*ptr1).basic_info).name
& finally by substituting ptr1 :
data = (*(*(production_plant_employees +i)).basic_info).name
%pformat specifier and cast them tovoid*:printf("production_plant_employees[%d].basic_info = %p", i, (void*)production_plant_employees[i].basic_info);Also,fflush(stdin);is undefined behavior.*) relative to the member-selection (.) and indirect member selection (->) operators.