473,769 Members | 2,501 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strndup: RFC

Hi
Reading comp.std.c I noticed that there was a message like this:
The WG14 Post Portland mailing is now available from the WG14 web site
at http://www.open-std.org/jtc1/sc22/wg14/

Best regards
Keld Simonsen

I went there and found that there is a report called
ISO/IEC JTC1 SC22 WG14 WG14/N1193
Specification for Safer C Library Functions —
Part II: Dynamic Allocation Functions

It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few weeks
ago.

It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing. Here is a proposed implementation. I would like
to see if your sharp eyes see any bug or serious problem with it.

Thanks in advance

jacob
---------------------------------------------------------cut here
#include <string.h>
#include <stdlib.h>
/*
The strndup function copies not more than n characters (characters that
follow a null character are not copied) from string to a dynamically
allocated buffer. The copied string shall always be null terminated.
*/
char *strndup(const char *string,size_t s)
{
char *p,*r;
if (string == NULL)
return NULL;
p = string;
while (s 0) {
if (*p == 0)
break;
p++;
s--;
}
s = (p - string);
r = malloc(1+s);
if (r) {
strncpy(r,strin g,s);
r[s] = 0;
}
return r;
}

#ifdef TEST
#include <stdio.h>
#define MAXTEST 60
int main(void)
{
char *table[MAXTEST];
char *str = "The quick brown fox jumps over the lazy dog";

for (int i=0; i<MAXTEST;i++) {
table[i] = strndup(str,i);
}
for (int i=0; i<MAXTEST;i++) {
printf("[%4d] %s\n",i,table[i]);
}
return 0;
}
#endif
Dec 2 '06 #1
68 7066
jacob navia said:

<snip>
I would like
to see if your sharp eyes see any bug or serious problem with it.
I don't see any serious problem with the code in terms of meeting its
specification, although I would consider replacing
strncpy(r,strin g,s);
with:

memcpy(r, string, s);

since you've already detected the terminator and know precisely where it is.

The thing that does concern me is the spec itself, which seems to me to
suffer from the same flaw as strncpy - i.e. it gives no indication of
whether truncation occurred. But of course that's a design issue, not a C
issue.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 2 '06 #2
Richard Heathfield a écrit :
jacob navia said:

<snip>
>>I would like
to see if your sharp eyes see any bug or serious problem with it.


I don't see any serious problem with the code in terms of meeting its
specification, although I would consider replacing

> strncpy(r,strin g,s);


with:

memcpy(r, string, s);

since you've already detected the terminator and know precisely where it is.

The thing that does concern me is the spec itself, which seems to me to
suffer from the same flaw as strncpy - i.e. it gives no indication of
whether truncation occurred. But of course that's a design issue, not a C
issue.
Interesting. I did not think about that.

You know of a version that gives that information back to the user?
It is sometimes important to know.

< off topic>
Since lcc-win32 supports optional arguments I could do:
char *strndup(char *str,size_t siz,bool *pTruncated=NUL L);
strndup(str,30) would be strndup(str,30, NULL)...
< / off topic >
Dec 2 '06 #3
In article <cK************ *************** ***@bt.com>,
Richard Heathfield <rj*@see.sig.in validwrote:
>The thing that does concern me is the spec itself, which seems to me to
suffer from the same flaw as strncpy - i.e. it gives no indication of
whether truncation occurred. But of course that's a design issue, not a C
issue.
When I've used my own version of strndup, it's always been make an
ordinary string from a "counted" string, so there is no question of
truncation. I suspect this is the more common use of it, rather than
copying a string to a buffer that might not be big enough.

-- Richard
--
"Considerat ion shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Dec 3 '06 #4
jacob navia wrote:
It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few weeks
ago.

It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing. Here is a proposed implementation. I would like
to see if your sharp eyes see any bug or serious problem with it.
What would the point of strndup be? It allocates the memory so there
really isn't a problem of an overflow. If you're low on memory ... why
are you duplicating a string?

Me thinks this is a solution looking for a problem [not directed at you
specifically Jacob, just the whole question of whether we should care
about strndup at all].

Tom

Dec 3 '06 #5
jacob navia wrote:
It proposes strdup and strndup too. Lcc-win32 proposes already strdup,
but strndup was missing. Here is a proposed implementation. I would like
to see if your sharp eyes see any bug or serious problem with it.
....
---------------------------------------------------------cut here
#include <string.h>
#include <stdlib.h>
/*
The strndup function copies not more than n characters (characters that
follow a null character are not copied) from string to a dynamically
allocated buffer. The copied string shall always be null terminated.
*/
char *strndup(const char *string,size_t s)
I haven't looked at the code, but I am a big believer in accurate
documentation.

Your comment references "n characters", but defines a parameter s. Is
that n? The comment doesn't say how many characters are copied, only
that it is not more than n, so I can't rely on the function to copy the
full strlen(string), even if s exceeds this. I suggest calling the
result a dynamically allocated char array, rather than a buffer, since
it isn't necessarily buffering anything. As a matter of fact, since it
is presumably sized to the input string, there probably isn't room for
additional characters to be added later, thus not used as a buffer.

The description doesn't say what the results are if insufficient memory
exists for the new array.

--
Thad
Dec 3 '06 #6
Richard Tobin said:
In article <cK************ *************** ***@bt.com>,
Richard Heathfield <rj*@see.sig.in validwrote:
>>The thing that does concern me is the spec itself, which seems to me to
suffer from the same flaw as strncpy - i.e. it gives no indication of
whether truncation occurred. But of course that's a design issue, not a C
issue.

When I've used my own version of strndup, it's always been make an
ordinary string from a "counted" string, so there is no question of
truncation. I suspect this is the more common use of it, rather than
copying a string to a buffer that might not be big enough.
No, that's not more common - it's just a more *intelligent* use of strncpy.
By far the most common usage of strncpy is from the cargo cult bunch: "I'm
smart, I know about buffer overruns, I know I should use strncpy instead of
strcpy, oops, oh look, I just threw away data, ohdearhowsadnev ermind."

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 3 '06 #7
jacob navia said:
You know of a version that gives that information back to the user?
No, but that doesn't mean much because I know of no version of strndup
whatsoever, apart from the one you just posted. I don't see any particular
use for it, so I've never gone looking for it. (That is not the same as
saying it's useless - one man's useless is another man's essential.)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 3 '06 #8
Tom St Denis wrote:
jacob navia wrote:
>It proposes really interesting functions, among others getline and
getdelim, that I introduced into lcc-win32 (by coincidence) a few
weeks ago.

It proposes strdup and strndup too. Lcc-win32 proposes already
strdup, but strndup was missing. Here is a proposed implementation.
I would like to see if your sharp eyes see any bug or serious
problem with it.

What would the point of strndup be? It allocates the memory so
there really isn't a problem of an overflow. If you're low on
memory ... why are you duplicating a string?

Me thinks this is a solution looking for a problem [not directed at
you specifically Jacob, just the whole question of whether we should
care about strndup at all].
I can see a possible use for it - to duplicate the initial portion
of a string only, i.e. to truncate it on the right.

#include <stdlib.h>
#include <stddef.h>

/* The strndup function copies not more than n characters
(characters that follow a null character are not copied)
from string to a dynamically allocated buffer. The copied
string shall always be null terminated.
*/
char *strndup(const char *_string, size_t _len) {
char *s, *p;

if ((p = s = malloc(_len + 1))) {
if (_string) /* else interpret NULL as empty string */
while (_len-- && (*p++ = *_string++)) continue;
*p = '\0';
}
return s;
} /* strndup, untested */

However N1193 is, in general, a Microsoft proposal, not a
standard. It is their lame attempt to catch their own foolish
clueless programmers. It is ugly, ugly, ugly.

BTW, Jacobs code carelessly fails to define size_t. It also return
NULL for other reasons than lack of memory, which can only cause
confusion.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>
Dec 3 '06 #9
CBFalconer a écrit :
BTW, Jacobs code carelessly fails to define size_t.
???
I have
#include <stdlib.h>
and that file includes stddef.h that defines size_t

It also return
NULL for other reasons than lack of memory, which can only cause
confusion.
??? Why confusion?

Null means failure
Dec 3 '06 #10

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

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.