Pre-C99 code would do it like this:
Code:
#include <stdio.h>
#include <stdlib.h>

struct test {
  int a[1];
};

int main() {
  size_t struct_size = sizeof(struct test);
  size_t array_size = 5 * sizeof(int);
  struct test *p = malloc(struct_size + array_size);

  if (p) {
    int i;

    for (i = 0; i < 5; i++) p->a[i] = i + i;
    for (i = 0; i < 5; i++) printf("%d\n", p->a[i]);
  }

  return 0;
}
But since that's technically illegal, C99 made up its own variation using an incomplete array type as the last member for people who just had to have it:
Code:
struct test {
  int a[];
};
But since you already have an array of NUMCOURSES, there's no point in using a flexible array.