What is the purpose of the strdup() function in C?
From strdup man:
The strdup() function shall return a pointer to a new string, which is a duplicate of the string pointed to by s1. The returned pointer can be passed to free(). A null pointer is returned if the new string cannot be created.
It makes a duplicate copy of the string passed in by running a malloc and strcpy of the string passed in. The malloc'ed buffer is returned to the caller, hence the need to run free on the return value.
The most valuable thing it does is give you another string identical to the first, without requiring you to allocate memory (location and size) yourself. But, as noted, you still need to free it (but which doesn't require a quantity calculation, either.)
It's effectively doing the same as the following code:
char *strdup (const char *s) {
char *d = (char *)(malloc (strlen (s) + 1)); // Space for length plus nul
if (d == NULL) return NULL; // No memory
strcpy (d,s); // Copy the characters
return d; // Return the new string
}
In other words:
- It tries to allocate enough memory to hold the old string (plus a null character to mark the end of the string).
- If the allocation failed, it sets
errno
toENOMEM
and returnsNULL
immediately (setting oferrno
toENOMEM
is somethingmalloc
does so we don't need to explicitly do it in ourstrdup
). - Otherwise the allocation worked so we copy the old string to the new string and return the new address (which the caller is responsible for freeing).
Keep in mind that's the conceptual definition. Any library writer worth their salary should have provided heavily optimised code targeting the particular processor being used.
Having re-found this answer after some months, I think the code is better written as:
char *strdup (const char *s) {
char *d = (char *)(malloc (strlen (s) + 1)); // Allocate memory
if (d != NULL)
strcpy (d,s); // Copy string if okay
return d; // Return new memory
}
since it avoids the multiple return points.
I'm not usually too concerned by multiple return points, especially when you can see them all at a glance but, since some people feel quite strongly about it, I'll cater to their needs as well.
No point repeating the other answers, but please note that strdup() can do anything it wants from a C perspective, since it is not part of any C standard. It is however defined by POSIX.1-2001.
I feel that this is a question which is simple enough that it should be answered on your own, and not through a community like SO.
Option a: man strdup
Option b: source of strdup
in libc
char * strdup(const char * s)
{
size_t len = 1+strlen(s);
char *p = malloc(len);
return p ? memcpy(p, s, len) : NULL;
}
May be a bit faster than with strcpy as the \0 char doesn't need to be searched again (it already was with strlen).