Home > Net >  Problem with pointer in array of structs in C
Problem with pointer in array of structs in C

Time:11-21

A problem stops the program working correctly. I guess it is related with using pointer in array of structs. Despite trying many ways, nothing could find out:

#include <stdio.h>

typedef struct {
    char* courseName;
    char* courseDate;
    double grade;
}EXAM;

int main() {

    double averageGrade = 0;
    EXAM *exams[5];

    for(int i = 0; i < 5; i  ){
        printf("Please enter course name:\n");
        scanf("%s", exams[i]->courseName);

        printf("Please enter course date:\n");
        scanf("%s", exams[i]->courseDate);

        printf("Please enter course grade:\n");
        scanf("%lf", &exams[i]->grade);

        averageGrade  = exams[i]->grade;
    }

    averageGrade /= 5;
    printf("Your average grade is: %.1lf.", averageGrade);

    return 0;
}

CodePudding user response:

1:

typedef struct {
    char* courseName;
    char* courseDate;
    double grade;
}EXAM;

Having defined courseName and courseDate as 'char *' means that they are only pointers. Pointers that without any allocation point to either NULL or more probably to garbage. How to fix it?
Either define your structure with statically allocated char arrays, like:

typedef struct {
    char courseName[41];
    char courseDate[41];
    double grade;
}EXAM;

or allocate them dynamically before signing anything into them:

for (int i = 0; i < 5; i  ) {
    exams[i]->courseName = (char *) calloc(41, sizeof(char));
    exams[i]->courseDate = (char *) calloc(41, sizeof(char));
}

In both cases you should make sure, that user doesn't overflow this fields so instead of "%s" in scanfs I would suggest using "@[^\n]", which is simply Get up to 40 characters from user until you find a '\n' character (user hits enter).
In addition in first case, you should make sure that both strings are null-terminated strings, a simple way to do it is to set zeros in all tables.

memset(exams, 0, sizeof(EXAM)*5);

2:

EXAM *exams[5];

This are also only pointers. That unallocated point to NULL or garbage. Go with either:

EXAM exams[5];

and use '.' instead of '->'.
or allocate them:

for (int i = 0; i < 5; i  ) {
    exams[i]= (EXAM *) calloc(1, sizeof(EXAM));
}

CodePudding user response:

EXAM[*] points to unallocated memory:

To create an array of 5 exam objects do:

EXAM exams[5]; // Note there is no * character.

If the pointer is necessary for some reason, then you will need to allocate space for these objects:

EXAM *exams[5];
for (int i=0; i<5; i  ) {
  exams[i] = calloc(1, sizeof(EXAM));
}

You also need to allocate space for the strings:

In C, when you use scanf on a %s, the space for that string must already be allocated.

So you should either use char courseName[256];, allocate sufficient space on the heap for the string, or use functions like getline() which will allocate the space for you.

  • Related