3

I couldn't think of a proper title to my question so here it goes. I am trying to learn C and the following code is from the tutorial I am following.

struct Person {
    char *name;
    int age;
    int height;
    int weight;
};

struct Person *Person_create(char *name, int age, int height, int weight){
    struct Person *who = malloc(sizeof(struct Person));
    assert(who != NULL);

    who->name = strdup(name);
    who->age = age;
    who->height = height;
    who->weight = weight;

    return who;
}

void Person_destroy(struct Person *who){
    assert(who != NULL);

    free(who->name);
    free(who);
}

int main(int argc, char *argv[]){
    struct Person *joe = Person_create("Joe Alex", 32, 64, 140);

    ........

My question is in Person_create function why are we duplicating name to a new memory location for who->name . Why can't we just make who->name point to the same location provided by the *name supplied to the function.
Also if we directly assigned the address of *name to who->name do we have to free it in Person_destroy.

MiJo
  • 569
  • 5
  • 19

2 Answers2

6

Why can't we just make who->name point to the same location provided by the *name supplied to the function.

For me this who->name = strdup(name); is better than this who->name = name; if i know i will modify the string pointed by name later somewhere.

So you might as well do this:

who->name = name;

However a string literal like "Joe Alex" is in a read-only location - so if you wanted to do something like this (later in some part of your code):

who->name[3] = 'x';

you would get segmentation fault. So if you want to modify it you would like to malloc some writable space from heap which strdup does for you.

You might want to have a look at: Modifying String Literal

Community
  • 1
  • 1
Sadique
  • 22,572
  • 7
  • 65
  • 91
-2

The char array *name is not an allocated array, that means if you leave your function scope, this array is not usable anymore. So the tutorial copies it in order to do operations later on this variable. Moreover, if you directly assigned your variable *name to who->name you must not free it because it was not returned by malloc.

Tristan Djahel
  • 1,082
  • 2
  • 12
  • 22
  • This is not true, since the value of `name` can still be used. Just any reference to the variable will be invalid, not it's value. – Philipp Murry Dec 22 '14 at 09:22
  • @PhilippMurry The bit about not freeing `who->name` if it was directly assigned with address of `name` is true right?. As mentioned in @al-Acme's answer the original `name` is not on the heap. – MiJo Dec 22 '14 at 09:33
  • If it's not on the heap, then that's true. As a rule of thumb: For each call to malloc/calloc, there must be one call to free. Not more and not less. So if it's not on the heap, there was never a call to malloc/calloc, and therefore no call to free is needed. – Philipp Murry Dec 22 '14 at 09:46