90

I read that strcpy is for copying a string, and strdup returns a pointer to a new string to duplicate the string.

Could you please explain what cases do you prefer to use strcpy and what cases do you prefer to use strdup?

johan
  • 1,943
  • 10
  • 31
  • 43

6 Answers6

126

strcpy(ptr2, ptr1) is equivalent to while(*ptr2++ = *ptr1++)

where as strdup is equivalent to

ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);

(memcpy version might be more efficient)

So if you want the string which you have copied to be used in another function (as it is created in heap section) you can use strdup, else strcpy is enough.

Antonio
  • 19,451
  • 13
  • 99
  • 197
Abdul Muheedh
  • 1,381
  • 1
  • 8
  • 4
  • 7
    Good answer apart from the last sentence, which is confusing. I guess you mean the lifetime of the `strdup()`ed string can extend beyond the end of the current function, but that could be the case anyway (if the target of `strcpy()` is a caller-provided buffer, a global variable, or itself manually allocated using `malloc()` or `new`). – j_random_hacker Dec 24 '12 at 12:05
  • 1
    Yes it is true that if the caller-provided buffer is a global variable or a dynamic pointer by itself then no need to use strdup I have just pointed one of the use case scenarios and thanks for completing it. – Abdul Muheedh Dec 24 '12 at 12:42
  • 12
    Really love the `while(*ptr2++ = *ptr1++)`! :) – Aloys Jun 11 '13 at 21:56
  • 1
    In the while loop, how does the exit condition work? – sbhatla Dec 05 '16 at 00:33
  • 5
    @sbhatla In C strings are ended by a nulbyte, which evaluates to false, and an assignment expression evaluates to the assigned value. –  Feb 07 '17 at 16:49
  • @Aloys If you do use an explict `while(*ptr2++ = *ptr1++)` in your program, don't forget to restore the pointers to their original values. After the `while` they'll be positioned at the null terminator. – Paulo Carvalho Aug 23 '23 at 14:37
68

The functions strcpy and strncpy are part of the C standard library and operate on existing memory. That is, you must provide the memory into which the functions copy the string data, and as a corollary, you must have your own means of finding out how much memory you need.

By constrast, strdup is a Posix function, and it performs dynamic memory allocation for you. It returns a pointer to newly allocated memory into which it has copied the string. But you are now responsible for this memory and must eventually free it.

That makes strdup one of the "hidden malloc" convenience functions, and that's presumably also why it is not part of the standard library. As long as you use the standard library, you know that you must call one free for every malloc/calloc. But functions such as strdup introduce a hidden malloc, and you must treat it the same as a malloc for the purpose of memory management. (Another such hidden allocation functions is GCC's abi::__cxa_demangle().) Beware!

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
18

strdup allocates memory for the new string on the heap, while using strcpy (or its safer strncpy varient) I can copy a string to a pre allocated memory on either the heap or the stack.

Oren
  • 4,152
  • 3
  • 30
  • 37
  • 1
    Why the emphatic "either"? Is it not possible to use `strcpy` to copy into a static buffer? – Kerrek SB Dec 24 '12 at 12:30
  • I attempted to stress the difference in usage between the two functions without cluttering the answer with too many memory managment issues. but yes you are correct about static buffers. – Oren Dec 24 '12 at 12:42
  • If you don't want clutter, you can just end the answer after "pre allocated memory" :-) – Kerrek SB Dec 24 '12 at 12:51
  • small nitpick: strncpy isn't safer than strcpy, as it does not guarantee that dest will be null terminated. Even worse, any unused space in the dest buffer will be filled with null terminators. This function was never intended for general usage. If you must use one of these functions, it's best to use strcpy and manually terminate dest. – JohnF Nov 18 '13 at 09:27
15

In the accepted answer, the implementation of strdup is presented as:

ptr2 = malloc(strlen(ptr1)+1);
strcpy(ptr2,ptr1);

However, that is somewhat sub-optimal because both strlen and strcpy need to find the length of the string by checking if each character is a \0.

Using memcpy should be more efficient:

char *strdup(const char *src) {
    size_t len = strlen(src) + 1;
    char *s = malloc(len);
    if (s == NULL)
        return NULL;
    return (char *)memcpy(s, src, len);
}
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • 1
    Good answer that separates the conceptual use of `strcpy` to implement `strdup` from the practicality of doing so in an efficient way. – Michael Gaskill Jun 25 '16 at 22:40
  • Given that memcpy is dependent upon knowing string length, strlen is going to be called in either case. memcpy itself is equivalent to `while ( len-- ) { *ptr2++ = *ptr1++ }`, which each time does a subtraction, assignment, and test for zero, and then still has to run an assignment and then two post increments and their assignments anyways. So this memcpy technique seems less efficient. These seem like rather trivial distinctions and imaginary optimizations. –  Apr 17 '19 at 06:04
0

char *strdup(char *pszSrch);

strdup will allocate storage the size of the original string. If storage allocation is successful, the original string is copied to the duplicate string.

strdupd return NULL on failure. If memory is not allocated, copy fails strdup return NULL.

tijko
  • 7,599
  • 11
  • 44
  • 64
0

for *memcpy another implementation is possible without incremental of dest and src :

while ( n-- ) { dest[n] = src[n] }

Soso Nada
  • 1
  • 1