473,656 Members | 2,756 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strdup()

As far as I can tell, strdup() is neither in C89 nor in C99.

Is that correct?

<OT>Is it in POSIX perhaps?</OT>
Nov 14 '05 #1
32 6365
Grumble <de*****@kma.eu .org> writes:
As far as I can tell, strdup() is neither in C89 nor in C99.

Is that correct?
Yes.
<OT>Is it in POSIX perhaps?</OT>


I believe so.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #2
On Tue, 22 Mar 2005 10:37:25 +0100, Grumble
<de*****@kma.eu .org> wrote:
As far as I can tell, strdup() is neither in C89 nor in C99.

Is that correct?
Correct. It's trivial to implement, though:

#include <stdlib.h>
char *strdup(const char *str)
{
char *cpy = NULL;
if (str)
{
cpy = malloc(strlen(s tr)+1);
if (cpy)
strcpy(cpy, str);
}
return cpy;
}

(Actually, POSIX doesn't specify what happens if a null pointer is
passed in, but I prefer the trivial test so that strdup(NULL) == NULL.)
<OT>Is it in POSIX perhaps?</OT>


It is. Some useful URLs for POSIX:

http://www.opengroup.org/onlinepubs/...9/nfindex.html
http://www.opengroup.org/onlinepubs/007908799/toc.htm
http://www.everything2.com/?node=Posix

Chris C
Nov 14 '05 #3
"Grumble" <de*****@kma.eu .org> wrote in message
As far as I can tell, strdup() is neither in C89 nor in C99.

Is that correct?
sure
<OT>Is it in POSIX perhaps?</OT>


strdup() was manditory in UNIX 95.

http://www.unix.org/

--
Tor <torust AT online DOT no>

Nov 14 '05 #4
Grumble wrote:
As far as I can tell, strdup() is neither in C89 nor in C99.

Is that correct?

<OT>Is it in POSIX perhaps?</OT>


Here are my replacements for strdup (specified in POSIX) and
strndup (an extension from GNU libc).

/*
dupstr() and dupstrn(): Replacements for strdup() and strndup()

Written in 2004 by Robert Bachmann <rbach [AT] rbach.priv.at>
Public domain.
*/

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

/*
char* dupstr (const char *s)

Returns a pointer to a new string
which is a duplicate of the string s,
or NULL if malloc() failed.
*/
char* dupstr (const char *s)
{
char *p;
size_t n;

assert(s != NULL);

n=strlen(s) + 1;
p = malloc(n);

if (p)
p=memcpy(p,s,n) ;

return p;
}

/*
char* dupnstr (const char *s,size_t n)

Works like dupstr() but it only copies the
first n characters.
A terminating '\0' is *always* added.
*/
char* dupnstr (const char *s,size_t n)
{
char *p;

assert(s != NULL);

p = malloc(n+1);

if (p) {
p=strncpy(p,s,n );
p[n]='\0';
}
return p;
}

--
Robert Bachmann <ne**@rbach.pri v.at>, PGP-KeyID: 0x8994A748
Nov 14 '05 #5
Robert Bachmann wrote:
.... snip ...
Here are my replacements for strdup (specified in POSIX) and
strndup (an extension from GNU libc).

/*
dupstr() and dupstrn(): Replacements for strdup() and strndup()

Written in 2004 by Robert Bachmann <rbach [AT] rbach.priv.at>
Public domain.
*/

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

/*
char* dupstr (const char *s)

Returns a pointer to a new string
which is a duplicate of the string s,
or NULL if malloc() failed.
*/
char* dupstr (const char *s)
{
char *p;
size_t n;

assert(s != NULL);

n=strlen(s) + 1;
p = malloc(n);

if (p)
p=memcpy(p,s,n) ;

return p;
}

/*
char* dupnstr (const char *s,size_t n)

Works like dupstr() but it only copies the
first n characters.
A terminating '\0' is *always* added.
*/
char* dupnstr (const char *s,size_t n)
{
char *p;

assert(s != NULL);

p = malloc(n+1);

if (p) {
p=strncpy(p,s,n );
p[n]='\0';
}
return p;
}


Try this modification (untested) which does reasonable things with
NULL input and eliminates the assert.

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

char *dupstr(const char *s)
{
char *p;
size_t n;

if (!s || !(p = malloc(n = 1 + strlen(s))) return NULL;
else return memcpy(p, s, n);
}

and dupnstr is probably better built out of strlcpy from the BSD
world, an implementation of which is available on my site
<http://cbfalconer.home .att.net/download/>. There is no need to
insert those possibly very length strings of zeroes.

--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
Nov 14 '05 #6
In article <42************ ***@yahoo.com>, CBFalconer wrote:
Robert Bachmann wrote:

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

/*
char* dupstr (const char *s)

Returns a pointer to a new string
which is a duplicate of the string s,
or NULL if malloc() failed.
*/
char* dupstr (const char *s)
{
char *p;
size_t n;

assert(s != NULL);

n=strlen(s) + 1;
p = malloc(n);

if (p)
p=memcpy(p,s,n) ;

return p;
}

[...]

Try this modification (untested) which does reasonable things with
NULL input and eliminates the assert.

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

char *dupstr(const char *s)
{
char *p;
size_t n;

if (!s || !(p = malloc(n = 1 + strlen(s))) return NULL;
else return memcpy(p, s, n);
}


I would argue that your version is inferior because it masks the bug of
passing a null pointer to dupstr(), and there is no convenient way to
distinguish between this bug and failure to allocate memory. How is the
caller supposed to put your check to good use? Although the standard
does not say anything about errno being set to an appropriate error code
when malloc() fails, the ``Quality of Implementation' ' factor is usually
such that malloc() does this. Therefore, callers of this function may
reasonably wish to rely on a meaningful errno value in order to diagnose
the error as ``dupstr() failed becaue of ...'' rather than ``dupstr()
failed for an unknown reason'':

char *p = dupstr(str);
if (p == NULL) {
perror("dupstr failed");
/* handle error */
}

If you really wish to keep the null pointer check, it is more useful to
set errno accordingly;

if (s == NULL) {
errno = EINVAL;
return NULL;
} else if ((p = malloc(n = strlen(s) + 1)) == NULL) {
return NULL;
}

(Of course, this decreases portability for no good reason because EINVAL
is not standard so it is not a very good solution either.)

--
My real email address is ``nils<at>gnuli nux<dot>nl''
Nov 14 '05 #7
"Nils Weller" <me@privacy.net > wrote in message

<snip>
char *p = dupstr(str);
if (p == NULL) {
perror("dupstr failed");
/* handle error */
}

If you really wish to keep the null pointer check, it is more useful to set errno accordingly;

if (s == NULL) {
errno = EINVAL;
return NULL;
} else if ((p = malloc(n = strlen(s) + 1)) == NULL) {
return NULL;
}

Normally, a "mean and lean" attitude is sufficient. Why keep
on going -- if there isn't going to be done any recovery of
malloc failures anyway?

/* Warning: untested code follows ...*/
/* xmalloc: exit on failure */
void *xmalloc(size_t size)
{
void *mem;

/* pre-condition catch implementation defined behavoir */
assert (size > 0);

mem = malloc(size);
if (mem == NULL)
{
perror("xmalloc : Out of memory");
exit(EXIT_FAILU RE);
}

return mem;
}

then our "strdup" can simply be written

/* xstrdup: exit on failure, never return NULL */
char *xstrdup(const char *str)
{
char *mem;

/* pre-condition catch UB */
assert(str != NULL);

mem = xmalloc(strlen( str) + 1);

/* post-condition */
assert(mem != NULL);

return strcpy(mem, str);
}

This simplify coding, since a lot if tests for NULL can be removed.
However, for a non-stop server, more advanced mem handling
is wanted, perhaps even using a GC.

--
Tor <torust AT online DOT no>

Nov 14 '05 #8
Tor Rustad wrote:
Normally, a "mean and lean" attitude is sufficient. Why keep
on going -- if there isn't going to be done any recovery of
malloc failures anyway?


Oh my.
Nov 14 '05 #9
>Normally, a "mean and lean" attitude is sufficient. Why keep
on going -- if there isn't going to be done any recovery of
malloc failures anyway?


I hope you don't design airplanes, nuclear power plants,
weapons systems, or firmware for automobile engines :-)

Gordon L. Burditt
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
23624
by: Allan Bruce | last post by:
Hi there, I have a program written in c++ and I wish to use a similar function to strdup(). The reason I have problems is that the char array requires freeing to avoid a memory leak, but I get problems using delete; e.g. char *NewCharArray;
6
2935
by: Stefan Schwärzler | last post by:
Hi Ng, habe nicht besonders viel Erfahrung in C und C++, deshalb: möchte den befehl strdup in <string.h> verwenden. #include <string.h> attrib(char *name, char *val) : name(strdup(name)), val(strdup(val)), next(0) { CDEBUG(printf("attrib::attrib(%s, %s)\n", name, val)); }
37
4295
by: priya | last post by:
Hi all, I am using strdup() in my c program..But I am having some pr0blem while using the free() in my c code.here I am pasting the my code. #include <stdio.h>
53
651
by: klaushuotari | last post by:
Sorry to bother you, but I just have to. What about strdup()? It wasn't in standard C run-time library, yet many apps use it liberally as it was in there. I don't know if that particular function is included in C99. Not too difficult to code own version of it, but why it wasn't included in library in the first place? Is there some rationale behind it? There are peculiar and dangerous functions like strtok(), so why not strdup() which...
20
6116
by: Michael Holm | last post by:
Ever so often when I try to compile some open source code, I get a error, pbrtparse.y(205) : error C3861: 'strdup': identifier not found In the example, I'm trying to compile pbrt (http://www.pbrt.org/). And I have been searching all over the net for it, and it seems I'm the only one having a problem with strdup. What do I do wrong?
5
3338
by: lovecreatesbea... | last post by:
I am trying the FREE net-snmp library things. Like the FREE libxml++ library, it lacks of a reasonable document on its API. Its very begining example code compiles and runs. It says "blah blah .." when I substitute the host address for a snmp equipped machine ``192.168.5.10'' within our LAN like this: session.peername = strdup("192.168.5.10"); Is strdup still in use? Is there anything prevents the code from becoming these:
10
3913
by: thomas | last post by:
Hi, It's known that strdup() returns a char* type, but sometimes the following code generates warning messages. char *x = ... char *p = strdup(x); You must change it to
0
8297
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8498
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7311
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6162
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5629
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4150
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4300
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1930
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.