Ex16.c Why use strdup()?

Regarding char *name in struct Person. I understand that if we create a struct Person without strdup(), malloc only allocates memory for the char pointer.

However, with gcc the code compiles and works fine without using strdup(), i.e. who->name = name. So my question is what advantages does strdup bring?

strdup duplicates the string.

char *name = "Michael";
who->name = name;

Here a pointer to the character array name is stored in who, but when name goes out of scope, the pointer will point to some memory location on the stack that is no longer valid, or indeed protected from being used by other functions. I guess you were just lucky that that hadn’t happened yet, or you used the struct in the same function where the original array was created.

char *name = "Michael";
who->name = strndup(name, MAX_LEN);
/* do stuff */
free(who->name);

Here the array is duplicated on the heap. When name goes out of scope, the copy will persist and you can safely continue to use who, you just need to remember to destroy the copy when you’re done.

In general, if you have some kind of data objects, you want to make sure that all their data is “in an independent, safe place” – unless you really know what you’re doing. The necessity for this kind of memory management is a big source for bugs in C, but it also makes the language interesting and challenging to work with. You’re closer to the machine than with more abstract modern languages that do all of this for you behind the scenes.

Ahh, yes, I was using the struct in the same function as the original. Thank you for the clarification.

Incidentally, the fact that gcc compiles a C program is by no means a proof of correctness or safety. In C you must test everything. Twice.
As I read the other day: C is like a high end racing car with very questionable brakes and no seat belts. It’s powerful and extremely fast, but it will happily oblige no matter what you tell it to do…