Thanks for help in advance.
~Naren
--
comp.lang.c.moderated - moderation address: cl...@plethora.net
memcpy is designed for copying a chunk of memory, of
specified length, from one place to another regardless
of the contents of that memory. strcpy is
specifically for copying zero (or null) terminated
strings around.
In practice, memcpy can be implemented as one or two
instructions on many types of computer hardware. strcpy,
however, is often implemented as a loop that copies
bytes until it finds a terminating null. For this
reason, memcpy is often significantly faster if you
know how much has to be copied in advance.
> Can anyone explain the difference between the memcpy() and strcpy()
> other than the strcpy() is null terminated by default.
No other difference. strcpy() could be defined as:
char *strcpy(char *to, const char *from)
{
return memcpy(to, from, strlen(from)+1);
}
(modulo "restrict" qualifiers)
strcpy() is a function, so it cannot be null terminated (and there is no
"default"). What is null terminated, is the data strcpy() copies. In fact,
null character is used to determine what amount of data should be copied,
which means that you cannot copy more than one zero byte using strcpy(). In
memcpy(), however, the amount of data to be copied is determined by
additional argument and the function doesn't care if there are any zeros in
the middle. There can be many of them, or none.
This brings the conclusion, that memcpy() and strcpy() are designed for
different jobs: strcpy() is for sequences of bytes of variable length (the
length of the sequence is determined by the position of the zero byte), also
known as strings; memcpy() is for blocks of data of known length, possibly
containing zeros (zero is not a special value for memcpy(), whereas it is
for strcpy()).
Note, that:
strcpy(a, b); <==> memcpy(a, b, strlen(b));
(forgetting the type of the return value)
But don't do that. The right-hand is slower.
Maciej Sobczak, http://www.cern.ch/Maciej.Sobczak
"in theory, there is no difference between theory and practice - but in
practice, there is"
> Can anyone explain the difference between the memcpy() and strcpy() other than the strcpy() is null terminated by default.
Imagine that you have a "string" in that it is an array of chars, but that
it has a byte with the value zero in the middle. strcpy() in this case
decides that is the end of the data it would like copied, unlike memcpy()
where you get to specify how much to copy.
This bit me a while ago when dealing with strings containing compressed
data from a file -- the data could contain these zero bytes in the middle.
Cheers,
Mikal
--
Michael Still (mi...@stillhq.com)
http://www.stillhq.com -- a whole bunch of Open Source stuff including PDF software...
"The Chad is great! The Chad is stuck!"
> Can anyone explain the difference between the memcpy() and strcpy()
> other than the strcpy() is null terminated by default.
It's not null-terminated by default --- it *always* is. I.e. if the
input isn't null-terminated, you're invoking undefined behaviour (BAD
boy!). If it is, the output will be, too.
The key difference is the determination how many bytes are to be
copied: in memcpy(), you tell it as the third argument; in strcpy(),
the occurence of the null terminator determines the end of what's
copied.
--
Hans-Bernhard Broeker (bro...@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
[ Please fix your line lenghts, btw. ]
> Can anyone explain the difference between the memcpy() and
> strcpy() other than the strcpy() is null terminated by default.
memcpy() takes destination, source and number of characters to copy.
Null termination is irrelevant to it.
strcpy() takes destination and source, and copies upto and including
null termination. Number of characters is irrelevant to it.
There is also strncpy(), which copies up to either number of characters
or null termination, whichever comes first, but it does have some
drawbacks.
Richard
Routines beginning with str, such as strcpy() are intended
to handle strings (yes, those thing "null terminated by default"
as you say) wheras routines beginning with mem, such as memcpy()
are intended for "copying blocks of raw memory" w/o considering
what objects may really be in the underlying memory.
So for instance, a distinction is being made between say
copying an array of char (use strcpy for instance) vs say
copying an array of ints or floats (use memcpy for instance).
--
Greg Comeau Countdown to "export": December 15, 2001
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
NEW: Try out libcomo! NEW: Try out our C99 mode!
com...@comeaucomputing.com http://www.comeaucomputing.com
> Can anyone explain the difference between the memcpy() and strcpy() other
> than the strcpy() is null terminated by default.
With memcpy, you specify the number of bytes that you want to copy,
and it copies them regardless of their content. With strcpy, you don't
specify a length, and it copies all the bytes up to and including the
first nul character.
Simplified Examples:
void *my_memcpy(void *dst, const void *src, size_t len)
{
void *old_dst = dst;
while( len-- > 0 )
*(unsigned char*)dst++ = *(unsigned char*)src++;
return old_dst;
}
char *my_strcpy(char *dst, const char *src)
{
char *old_dst = dst;
while( *dst++ = *src++ )
;
return old_dst;
>Can anyone explain the difference between the memcpy() and strcpy() other than the strcpy() is null terminated by default.
strcpy copies strings, memcpy copies character arrays. The former always
stops upon encountering a null character, the latter always copies the
specified number of characters.
Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
The mem*() functions operate on undifferentiated chunks of storage.
The str*() functions operate on null-terminated character strings.
strcpy must check for continuation after copying each character, memcpy
just does it. So copying 1000 chars with strcpy costs 1000 conditionals
(and none of those chars can contain '\0') copying 1000 chars with
memcpy can include embedded '\0'.
Quite a large difference
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
memcpy() copies exactly as many bytes as you tell it to do while strcpy()
copies characters until it finds the first '\0' (which is also copied).
Regards, Jens
--
_ _____ _____
| ||_ _||_ _| Jens.T...@physik.fu-berlin.de
_ | | | | | | AG Moebius, Institut fuer Molekuelphysik
| |_| | | | | | Fachbereich Physik, Freie Universitaet Berlin
\___/ens|_|homs|_|oerring Tel: ++49 (0)30 838 - 53394 / FAX: - 56046
Not to be picky, but strcpy() does not copy NULL terminated strings, it
copies
NUL terminated strings. NULL is a pointer concept, NUL is the
``zero-character.''
Read the CLCM FAQ. Also, that should be memcpy(a,b,strlen(b)+1) above
right?
(Sorry about that, I couldn't resist.)
Aside from that, there are a number of differences between strcpy and
memcpy
aside from the NUL byte. strcpy is almost always implemented as a simple
assembly
loop that copies bytes (sort of like):
while (*dst++ = *src++)
;
whereas memcpy is usually implemented using a more efficient
instruction. For
long runs, it could copy dwords (or words) depending on the
architecture. It
could be written using a Duffs-device loop to efficiently patch up
addresses on
non-aligned boundaries and then use the most efficient block copy that
the
architecture allows.
In general, memcpy() is going to be *alot* more efficient than strcpy.
However,
as was mentioned above, memcpy(a, b, strlen(b)+1) is usually not as
efficient as
strcpy. I guess that it could be for sufficiently large strings, but
that is
unlikely.
One thing to consider when thinking about memcpy is that it cannot be
used
reliably on overlapping memory (for example, memcpy(a, a+10, 10)) since
it can
do some really bad things. If you can't guarentee that your memory
regions don't
overlap, use memmove instead (but that is another story altogether).
For some more information on stuff like this, check out the CLCM FAQ at
http://www.eskimo.com/~scs/C-faq/top.html
It has some really nice sections on NUL and NULL (chapter 5), and
strcpy, strncpy,
and the like (questions 11.25 and 13.2 in particular).
D. Shawley
--
Unless the number of non-'\0' chars at "from" is greater than or equal to
the maximum value of size_t....
Tim Reid
--
nipson anomema mem onan opsin
Not only is this picky, it's wrong. The C standard does not
mention NUL. It does use the term null-terminated to refer to
strings. The zero character is called the null character in C.
--
Michael M Rubenstein
Which is not possible.
size_t is defined, in effect [I don't have the exact wording] as
an unsigned integral type that can represent the largest object
in the memory allocation model. In other words, it is not
possible to create a string with a length that can not be stored
in a size_t.
> > return memcpy(to, from, strlen(from)+1);
>
> Unless the number of non-'\0' chars at "from" is greater than or equal to
> the maximum value of size_t....
Hmm...
The non-'\0' characters and the '\0' must be part of the same
object; otherwise the "strlen" call is undefined. How would one
allocate such an object?
If it were allocated as a normal variable:
#define EXTRA_LARGE ((uintmax_t) SIZE_MAX + 1)
char jumbo[EXTRA_LARGE];
then sizeof(jumbo) could not return the correct value, because
its type is defined to be size_t. Is this allowed?
malloc(EXTRA_LARGE) would be no good either: the type of the
parameter is size_t, so it'd just wrap to malloc(0).
Is calloc(EXTRA_LARGE/2, 2) required to either do the job or
return NULL?
You already got the answer from Michael, the null-character is a valid
concept in C: look at 5.2.1-2 in the Standard.
> Also, that should be memcpy(a,b,strlen(b)+1) above
> right?
> (Sorry about that, I couldn't resist.)
You are absolutely right. I've been on the autopilot then... ;-)
> Aside from that, there are a number of differences between strcpy and
> memcpy
> aside from the NUL byte. strcpy is almost always implemented as a simple
> assembly
> loop that copies bytes (sort of like):
> while (*dst++ = *src++)
> ;
> whereas memcpy is usually implemented using a more efficient
> instruction. For
> long runs, it could copy dwords (or words) depending on the
> architecture. It
> could be written using a Duffs-device loop to efficiently patch up
> addresses on
> non-aligned boundaries and then use the most efficient block copy that
> the
> architecture allows.
>
> In general, memcpy() is going to be *alot* more efficient than strcpy.
> However,
> as was mentioned above, memcpy(a, b, strlen(b)+1) is usually not as
> efficient as
> strcpy. I guess that it could be for sufficiently large strings, but
> that is
> unlikely.
Yes, it's unlikely. strlen has to traverse the string anyway, testing only
one byte at a time. The underlying architecture can also help here (vide:
string instructions on Intel processors), but this also applies to the
strcpy. If you don't know the length of the string, strcpy is probably the
fastest you can get from the library. Combining memcpy with strlen is only
conceptual example and doesn't mean that the library is reduntant.
> One thing to consider when thinking about memcpy is that it cannot be
> used
> reliably on overlapping memory (for example, memcpy(a, a+10, 10)) since
> it can
> do some really bad things.
Same applies to strcpy() (undefined behaviour).
> If you can't guarentee that your memory
> regions don't
> overlap, use memmove instead (but that is another story altogether).
Another story is that copying overlapping strings (which can only mean that
you are copying one string over itself, because there can be only one null
character) is obscure and probably cries for redesigning of the whole
program.
>aside from the NUL byte. strcpy is almost always implemented as a simple
>assembly
>loop that copies bytes (sort of like):
> while (*dst++ = *src++)
> ;
>whereas memcpy is usually implemented using a more efficient
>instruction. For
>long runs, it could copy dwords (or words) depending on the
>architecture.
The same technique can be used for strcpy, too. My strcpy implementation
for ia64-glibc does the copying one 64-bit word at a time.
>In general, memcpy() is going to be *alot* more efficient than strcpy.
This is true, the fact that the byte count is known in advance allows for
much more aggressive optimisations, on certain platforms.
Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
Is it more or less like:
// [initial part to reach word alignment not shown]
for ( w = *(word *)q;
(w&0xFF) && (w&0xFF00) && .../* 8 terms altogether */;
p += sizeof(word), q += sizeof(word), w = *(word *)q )
*p = w;
while ( *p++ = *q++ )
; // handle final (maybe partial) word
That seems to burn a lot of cycles in the (first) loop test..
If you don't do that, how do you avoid copying too many bytes?
Also, it seems that the two pointers would be simultaneously
word-aligned only 1/8 of the time..
>Dan Pop wrote:
>> The same technique can be used for strcpy, too. My strcpy implementation
>> for ia64-glibc does the copying one 64-bit word at a time.
>
>Is it more or less like:
> // [initial part to reach word alignment not shown]
> for ( w = *(word *)q;
> (w&0xFF) && (w&0xFF00) && .../* 8 terms altogether */;
> p += sizeof(word), q += sizeof(word), w = *(word *)q )
> *p = w;
> while ( *p++ = *q++ )
> ; // handle final (maybe partial) word
>That seems to burn a lot of cycles in the (first) loop test..
>If you don't do that, how do you avoid copying too many bytes?
Writing it in assembly, I am not limited by what the C operators can
provide. I'm detecting the presence of a null byte in the word with
the ia64 czx1 instruction.
>Also, it seems that the two pointers would be simultaneously
>word-aligned only 1/8 of the time..
The pointers need not have similar alignment. The destination word is
obtained by combining parts of two source words. So, except for the
"prologue" and "epilogue" parts, all memory accesses are one word a time.
The code is available from:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/ia64/strcpy.S?rev=1.4&content-type=text/x-cvsweb-markup&cvsroot=glibc
I had a much more aggressive version, but it didn't pass the glibc
Stratcliff test: I was doing too much read ahead, to compensate the
memory access latency. This was OK for memcpy, because I knew exactly
when to stop reading ahead, but not for strcpy.
Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
> Dan Pop wrote:
> > The same technique can be used for strcpy, too. My strcpy implementation
> > for ia64-glibc does the copying one 64-bit word at a time.
>
> Is it more or less like:
> // [initial part to reach word alignment not shown]
> for ( w = *(word *)q;
> (w&0xFF) && (w&0xFF00) && .../* 8 terms altogether */;
> p += sizeof(word), q += sizeof(word), w = *(word *)q )
> *p = w;
> while ( *p++ = *q++ )
> ; // handle final (maybe partial) word
> That seems to burn a lot of cycles in the (first) loop test..
> If you don't do that, how do you avoid copying too many bytes?
There are much quicker fixed time ways of determining whether or not a word
contains a zero byte at which point you fall into the final naive loop.
Memory fails me as to the exact test though ... :-(
> Also, it seems that the two pointers would be simultaneously
> word-aligned only 1/8 of the time..
Theoretically, yes - but IMHO, it real life it will more often (than 1 in 8
times) be the case that the address of the first character of a string will
fall on a convenient address boundary as buffers for holding strings will
most likely have come back from a memory allocator that returns blocks of
memory aligned to the most general address boundary.
--
Stewart Brodie, Senior Software Engineer (Views expressed are my own and
Pace Micro Technology PLC not those of my employer)
645 Newmarket Road
Cambridge, CB5 8PB, United Kingdom WWW: http://www.pacemicro.com/