[net.unix] strdup

lcc.jbrown@ucla-locus.arpa (Jordan Brown) (08/26/86)

/* the following code is in the public domain.  I have never seen */
/* the original UNIX code for this function. */
/* hjb 08/25/86 */

char *
strdup(s)
char *s;
{
	char *p;
	extern char *malloc();

	if(p=malloc(strlen(s)+1))
		strcpy(p,s);
	return p;
}

I am not sure, but I think that strdup comes from MicroSoft, and is only
present under XENIX and their MSDOS C compiler.  It's a useful function,
though, and everybody should have it.

gwyn@BRL.ARPA (VLD/VMB) (08/27/86)

As a point of information, strdup() is listed in the SVR3 manual.

I'm not sure how useful it really is, since one still has to test
the returned pointer to handle the out-of-memory situation.  When
I implement my own strdup() in an application, instead of returning
NULL the function typically enters a termination routine.  That way
the main body of code remains simple and straightforward.  The exact
error handling approach is clearly application-specific; the problem
with strdup() is that many programmers will not bother to test for
failure, with the result of reduced code reliability.

heff@bsdpkh.UUCP (Paul K Heffner) (08/29/86)

hjb writes:

> /* the following code is in the public domain.  I have never seen */
> /* the original UNIX code for this function. */
> /* hjb 08/25/86 */
> 
> char *
> strdup(s)
> char *s;
> {
> 	char *p;
> 	extern char *malloc();
> 
> 	if(p=malloc(strlen(s)+1))
> 		strcpy(p,s);
> 	return p;
> }
> 
> I am not sure, but I think that strdup comes from MicroSoft, and is only
> present under XENIX and their MSDOS C compiler.  It's a useful function,
> though, and everybody should have it.

I'm using the latest release of the Software Generation System on an AT&T
3b2 and strdup is indeed found in STRING(3C). Following is the description
from the man page:

char *strdup (s1)
char *s1;

Strdup returns a pointer to a new string which is a duplicate of the string
pointed to by s1. The space for the new string is obtained using malloc(3C). If
the new string cannot be created, null is returned.

The above code doesn't return a null if malloc fails, so perhaps (for sake
of consistancy) the code should be changed to:

#define NULL (char *)0

char *
strdup(s)
char *s;
{
	char *p;
	extern char *malloc();

	if((p = malloc(strlen(s) + 1)) != NULL)
	{	strcpy(p,s);
		return p;
	}
	return NULL;
}

						Paul Heffner
					{ihnp4,akgua,attmail}!bsdpkh!heff

ark@alice.UucP (Andrew Koenig) (08/30/86)

> The above code doesn't return a null if malloc fails, so perhaps (for sake
> of consistancy) the code should be changed to:
> 
> #define NULL (char *)0
> 
> char *
> strdup(s)
> char *s;
> {
>	char *p;
>	extern char *malloc();
>
>	if((p = malloc(strlen(s) + 1)) != NULL)
>	{	strcpy(p,s);
>		return p;
>	}
>	return NULL;
> }

First of all, defining NULL as (char *) 0 is not a good idea.
A null pointer is guaranteed to compare equal to a constant 0,
so there's no need to cast that 0 to another type.  Moreover, if
you define NULL the way you have, you generally cannot use it
as a null pointer of any other type.

Second, malloc takes an unsigned argument, not an int.

Third, if malloc returns a null pointer which is then put in p,
saying "return p;" will return that null pointer.  Thus the program
can be shortened:

char *
strdup(s)
char *s;
{
	extern char *malloc();
	char *p = malloc ((unsigned) strlen (s) + 1);
	if (p)
		strcpy (p, s);
	return p;
}

(PS: I have never seen the original code to strdup() either)

levy@ttrdc.UUCP (Daniel R. Levy) (09/02/86)

In article <241@bsdpkh.UUCP>, heff@bsdpkh.UUCP (Paul K Heffner) writes:

>> /* hjb 08/25/86 */
>> char * strdup(s)
>> char *s;
>> {
>> 	char *p;
>> 	extern char *malloc();
>> 	if(p=malloc(strlen(s)+1)) strcpy(p,s);
>> 	return p;
>> }

>The above code doesn't return a null if malloc fails

It DOESN'T???  Gee, then maybe you have a busted malloc().  If malloc()
fails, it should return the null pointer.  That is what is being tested in
the clause 'if(p=malloc(strlen(s)+1))'.  As so many people have expounded
in net.lang.c:  a null pointer is semantically the same as zero in the C
language (except for sizeof(), should pointers exist of sizes other than
sizeof(int)).

So if malloc() fails, p gets NULL and the return value is likewise NULL.
The if() simply keeps strcpy from trying to copy something into an invalid
buffer ("pointed to" by NULL) should malloc() fail.  Then the user can catch
the error instead of the program dumping core.  Simple huh?

>
>						Paul Heffner
>					{ihnp4,akgua,attmail}!bsdpkh!heff
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
	   go for it!  			allegra,ulysses,vax135}!ttrdc!levy