tags:

views:

16025

answers:

7

What is the purpose of the strdup() function in C?

+8  A: 

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.

VonC
A: 

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.

jussij
A: 

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.)

le dorfier
+19  A: 

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:

  1. It tries to allocate enough memory to hold the old string (plus a null character to mark the end of the string).
  2. If the allocation failed, it sets errno to ENOMEM and returns NULL immediately (setting of errno to ENOMEM is something malloc does so we don't need to explicitly do it in our strdup).
  3. 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.

paxdiablo
It is worth noting, that as Pax' sample implementation implies, strdup(NULL) is undefined and not something you can expect to behave in any predicable way.
unwind
Also, I think malloc() would set errno, so you shouldn't have to set it yourself. I think.
Chris Lutz
That's a good point, @Chris. I changed it because I had a need to look at the man page for strdup() and noticed I'd left that out. But I forgot that malloc() did that for it. So I'll revert the code.
paxdiablo
+6  A: 

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.

Chris Young
+4  A: 

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

ephemient
RTFM pretty much covers the function
Daniel Goldberg
+2  A: 
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).

tristopia