Array of structs replacing values over itself

The strtok returns a pointer to the buffer and does not allocate memory. Since you do not copy the strings, you end up with lots of pointers pointing to the same buffer that is overwritten at each iteration of the loop.

To fix this, you need to change your loop to copy the strings using strdup:

while(fgets(buffer, sizeof(buffer), fp) != NULL)
{
    d[counter].name = strdup(strtok(buffer, del));
    d[counter].course = strdup(strtok(NULL, del));
    d[counter].grade = atoi(strtok(NULL, del));
    counter++;
}

Don’t forget to return the allocated memory with free once you no longer need the strings:

for (i = 0; i < counter; i++) {
   free(d[i].name);
   free(d[i].course);

   d[i].name = NULL;
   d[i].course = NULL;
}

Note that strdup is part of POSIX1.2001 standard, not part of C89. If it is not available, you’ll have to re-implement it yourself (quite easy):

char *my_strdup(const char *str) {
  char *copy;
  size_t len = strlen(str) + 1;
  if (len == 0) return NULL;
  copy = (char *)malloc(len);
  if (copy == NULL) return NULL;
  memcpy(copy, str, len);
  return copy;
}

Leave a Comment