As Johan Wentholt correctly outlined in his answer, you must allocate memory for both the Student
structure and the string its member name
points to, but you must return the new structure so the caller can do something with it:
Student *add_student(const char *student_name) {
Student *new_s = malloc(sizeof(Student));
if (new_s) {
new_s->name = strdup(student_name);
}
return new_s;
}
You code invokes undefined behavior because you did not allocate memory for the string, worse even, you left the name
member uninitialized (malloc
does not initialize the memory it returns).
Furthermore, you should not use strncpy
. It is not some safe version of strcpy
, it is a very error prone function, whose semantics are poorly understood by most programmers. NEVER use this function. If you see it used, there are chances you are either in front of a bug or there is a better method to replace it.
For completeness, your code:
strncpy(new_s->name, student_name, sizeof(new_s->name) - 1);
Would attempt to copy at most sizeof(char*)-1
characters from student_name
into the array pointer to by new_s->name
.
If the student_name
is longer, the destination will not be null terminated,
If it is shorter, the destination will be padded with null bytes upto the given size.
Here the destination pointer is uninitialized and the size information is bogus anyway: you really want to copy all characters in the string plus the null terminator, which is exactly what strcpy
does. But you need to allocate enough memory for that. You could use:
new_s->data = malloc(strlen(student_name) + 1);
strcpy(new_s->data, student_name);
The Posix function strdup()
does both operations in one call:
new_s->data = strdup(student_name);