How do I use strdup?

47,711

Solution 1

If you're using the POSIX standard strdup(), it calculates the space needed and allocates it and copies the source string into the newly allocated space. You don't need to do a malloc() yourself; indeed, it immediately leaks if you do it since you overwrite the only pointer to the space you allocated with the pointer to the space that strdup() allocated.

Hence:

char *variable = strdup(word);
if (variable == 0) …process out of memory error; do not continue…
…use variable…
free(variable);

If you do need to do the memory allocation, then you need to allocate strlen(word)+1 bytes in variable and you can then copy word into that newly allocated space.

char *variable = malloc(strlen(word)+1);
if (variable == 0) …process out of memory error; do not continue…
strcpy(variable, word);
…use variable…
free(variable);

Or calculate the length once and use memmove() or perhaps memcpy():

size_t len = strlen(word) + 1;
char *variable = malloc(len);
if (variable == 0) …process out of memory error; do not continue…
memmove(variable, word, len);
…use variable…
free(variable);

Don't forget to ensure you know where the free() is for every malloc().

Solution 2

you don't need to alloc space for use with strdup, strdup will do that for you. However you should free it after use.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main (){

    const char* s1= "Hello World";
    char* new = strdup (s1);
    assert (new != NULL);

    fprintf( stdout , "%s\n", new);

    free (new);
    return 0;
}

Edit: Be carefull with C++ as the variable name new is fine in C and not in C++ since it is a reserved name for operator new.

Solution 3

You seem confused. Forget what you know about pointers. Let's work with ints.

int x;
x = rand();    // Let us consider this the "old value" of x
x = getchar(); // Let us consider this the "new value" of x

Is there any way for us to retrieve the old value, or has it "leaked" from our view? As a hypothetical, suppose you were expected to let the OS know that you're finished with that random number, in order for the OS to perform some cleanup tasks.

Is the old value required for the generation of the new value? How can it be, when getchar can't see x?

Let us now consider your code:

char *variable;
variable = (char*) malloc(sizeof(char*)); // Let us consider this the "old value" of variable
variable = strdup(word);                  // Let us consider this the "new value" of variable

Is there any way for us to retrieve the old value, or has it "leaked" from our view? You're expected to let the OS know when you're finished with malloced memory, by calling free(variable);.

Is the old value required for the generation of the new value? How can it be, when strdup can't see variable?

FYI, here's an example of how strdup might be implemented:

char *strdup(const char *original) {
    char *duplicate = malloc(strlen(original) + 1);
    if (duplicate == NULL) { return NULL; }

    strcpy(duplicate, original);
    return duplicate;
}

Solution 4

As it currently stands you are always leaking 4 to 8 bytes (depending on your architecture). Regardless of strdup which will allocate the required dynamic memory on its own you are reassigning the only variable that holds the pointer to your newly malloced memory area.

Simply say

char* const variable = strdup(word);
Share:
47,711
Ivan Zhang
Author by

Ivan Zhang

Updated on July 28, 2022

Comments

  • Ivan Zhang
    Ivan Zhang almost 2 years

    I am calling strdup and have to allocate space for the variable before calling strdup.

    char *variable;
    variable = (char*) malloc(sizeof(char*));
    variable = strdup(word);
    

    Am I doing this right? Or is there something wrong here?

  • albttx
    albttx over 7 years
    You should not use new as variable name
  • hetepeperfan
    hetepeperfan over 7 years
    @ale-batt The variable name is perfectly fine in C. However, I can understand that the C++ compiler doesn't like it. This question is tagged as C. Hence, I don't see a problem.