baris_ercan
baris_ercan

Reputation: 152

Usage of strdup()

Let's say we have a struct :

struct Person {
    char *name;
};

struct Person *Person_create(char *name){
  struct Person *who = malloc(sizeof(struct Person));
  assert(who != NULL);
  who->name = strdup(name);
  return who;
}

void Person_destroy(struct Person *who){
  assert(who != NULL);
  free(who->name);
  free(who);
}

And the main function :

int main(int argc,char *argv[]){

  struct Person *mike = Person_create("mike");
  Person_print(mike);
  Person_destroy(mike);

  return 0;
}

The above code won't work properly without the strdup() function. Valgrind says that the address you try to free with free(who->name) is not malloced. What's the story behind this, didn't I malloc that memory when I malloced the struct? And what difference does the strdup() make?

Upvotes: 4

Views: 1715

Answers (3)

Nigel Harper
Nigel Harper

Reputation: 1250

Mallocing the struct allocates memory for the pointer name but it doesn't allocate any memory for name to point to. At that point who->name will be some random garbage value so freeing it makes no sense.

strdup uses malloc internally to allocate memory for the string it copies. Once you've got a pointer back from strdup you can, and should, free it when you're done.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320699

In your code each Person object involves two independent blocks of memory: the struct Person object itself and the separate memory block for the name. That separate memory block is pointed by the name pointer inside the struct. When you allocate struct Person by using malloc, you are not allocating any memory for the name. It is, again, an independent block of memory that should be allocated independently.

How you are planning to allocate memory for the name is entirely up to you. If you use strdup (which is essentially a wrapper for malloc) as in your code above, then you will have to free it by free in the end.

You did not explain what you mean by "without the strdup() function". What did you code look like without it? If you simply did

who->name = name;

then you made that who->name pointer to point directly to the string literal memory occupied by literal "mike". String literals reside in static memory. You are not allowed to free them. This is what valgrind is telling you.

Upvotes: 5

titer1_on_the_way
titer1_on_the_way

Reputation: 9

strdup do noes call malloc, it is only string operation. you only malloc the pointer to the struct ,not the inner member

Upvotes: -3

Related Questions