0

I have a struct gradebook with(among other things) an array of student structs that has two string fields

#define MAX_NAME_LEN 50
#define MAX_EMAIL_LEN 80
#define MAX_NUMBER_OF_STUDENTS 200
#define MAX_NUMBER_OF_ASSIGNMENTS 100

typedef struct students {
   char *name;
   char *email;
} Students;

typedef struct gradebook {
   int number_of_students;
   Students students[MAX_NUMBER_OF_STUDENTS];
   int number_of_assignments;
   char assignments[MAX_NUMBER_OF_ASSIGNMENTS][(MAX_NAME_LEN + 1)];
   int scores[MAX_NUMBER_OF_STUDENTS][MAX_NUMBER_OF_ASSIGNMENTS];
} Gradebook;

I have an initialization function

 int init_gradebook(Gradebook *book) {
   int row, col, ndx, count;

   book->number_of_students = 0;
   count += book->number_of_students;

   for(ndx = 0; ndx < MAX_NUMBER_OF_STUDENTS; ndx++) {
      book->students[ndx].name = 0;
      book->students[ndx].email = 0;
   }

   book->number_of_assignments = 0;
   count += book->number_of_assignments;

   for(row = 0; row < MAX_NUMBER_OF_ASSIGNMENTS; row++) {
      for(col = 0; col < (MAX_NAME_LEN + 1); col++) {
         book->assignments[row][col] = 0;
         count += book->assignments[row][col];
      }
   }

   for(row = 0; row < MAX_NUMBER_OF_STUDENTS; row++) {
      for(col = 0; col < MAX_NUMBER_OF_ASSIGNMENTS; col++) {
         book->scores[row][col] = 0;
         count += book->scores[row][col];
      }
   }

   if (count == 0) {
      return 1;
   } else {
      return 0;
   }

}

and I need to then insert, into those two string fields, the passed in strings, with my add_student function.

int add_student(Gradebook *book, char *nom, char *mail) {
   int ndx, count;

   if (book->number_of_students == 0) {
      book->students[(book->number_of_students)].name = malloc(sizeof(51));
      book->students[(book->number_of_students)].email = malloc(sizeof(81));
      strcpy(book->students[(book->number_of_students)].name, nom);
      strcpy(book->students[(book->number_of_students)].email, mail);
      book->number_of_students++;
   } else {
   for (ndx = 0; ndx < book->number_of_students; ndx++) {
      book->students[(book->number_of_students)].name = malloc(sizeof(51));
      book->students[(book->number_of_students)].email = malloc(sizeof(81));
      strcpy(book->students[(book->number_of_students)].name, nom);
      strcpy(book->students[(book->number_of_students)].email, mail);
      book->number_of_students++;
      }
   }

   return 1;
}

My code compiles, but when I run it with the main function, I get a seg fault. The add_student function is what I am ultimately trying to do (copy the given string into book->student[ndx].name) If you need to see the main file or the gradebook.h file, let me know.

Edit: Thanks to all of you, this issue has been solved. The main problem, as abginfo pointed out, was my If Else + the For loop inside of it. But now I have other problems further along in my program. Haha, Thank You.

7
  • Are you allocating memory to the Gradebook struct before passing its ref to the init function? Commented Dec 13, 2013 at 19:53
  • No I didn't. Do I need to do that in the same manner and I did with book->students[(book->number_of_students)].name = malloc(sizeof(51)); for example? Commented Dec 13, 2013 at 19:58
  • Doesn't cause the segfault but... in your add_student function, the if-else block doesn't seem right. Both actions should be the same regardless if number_of_students is 0. You should check for MAX_NUMBER_OF_STUDENTS though. Commented Dec 13, 2013 at 20:33
  • Oh gosh yeah, that would just start at 0 everytime and write over the first slot. Thanks, I'm going to change that now. Edit: I still have the "expected expression before ')' token" error after trying both suggestions from varevarao and agbinfo. Commented Dec 13, 2013 at 20:44
  • Welcome to SO. This is the moment to discover how a debubgger works. You will learn much more when doing this yourself than by letting others do that for you. Commented Dec 13, 2013 at 21:52

2 Answers 2

1

From what portion of your code I can see, I'm going to make the assumption that the init_gradebook function takes a non allocated reference to gradebook and attempts to initialize it. In this case the gradebook reference you have has no memory allocated to it just yet. Try using the malloc() function to assign the required memory to your gradebook reference before attempting to initialize the rest of its variables.

 gb = (Gradebook*)malloc(sizeof(*Gradebook));

I've changed the variable name to avoid any confusion.

Sign up to request clarification or add additional context in comments.

6 Comments

I used book = (book*)malloc(sizeof(book)); since that is the name of what is passed in(I'm hoping that it is equivalent) but now when compiling, I get "expected expression before ')' token" and all of the parenthesis are matched. I only added the line of code that you suggested.
book = (book*)malloc(sizeof(book)) should be book = (book*)malloc(sizeof(*book)). sizeof(book) is the size of a pointer.
I tried what you suggested (adding * before the third book), but I get the same error
If you've added the line exactly as I said, you might wanna change the 'gradebook' to 'Gradebook' considering your typedef. Also thanks @agbinfo, I'll make the correction.
@user2942904: What's the line at which you get the token error?
|
0

To supplement varevarao's answer, you should allocate everything explicitly as a matter of habit instead of relying on segfaults to tell you something's not allocated. (Not that you necessarily do!) Messing with unallocated memory is undefined behavior, so in some cases this code does not trigger an error -

int main (void) {
  Gradebook mybook;
  init_gradebook(&mybook);
  printf("there are %i students\n", mybook.number_of_students);
  add_student(&mybook, "blerf", "[email protected]");

  printf("now there are %i students\n", mybook.number_of_students);
  printf("%s has an email address of %s\n", mybook.students[0].name, mybook.students[0].email);
  return 0;
}

returned (on my machine)

there are 0 students
now there are 1 students
blerf has an email address of [email protected]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.