strcpy vs memcpy

P

Pallav singh

when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
Data Type

Thanks
Pallav
 
R

Richard Herring

In message
when we should use strcpy( ) and when memcpy( ) ?

Oversimplifying, of course:

Should? Never.
Must? When there's no other choice.

If you have a real problem which involves copying, post the code and
someone will be happy to advise.
 
T

Tim Slattery

Pallav singh said:
when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
Data Type

strcpy() is more convenient for strings, because it stops when it
finds a null byte. With memcpy you have to tell it when to stop. Use
whichever meets your needs.
 
J

Juha Nieminen

Tim said:
strcpy() is more convenient for strings, because it stops when it
finds a null byte. With memcpy you have to tell it when to stop. Use
whichever meets your needs.

memcpy() might be more efficient because its implementation might be
able to copy entire words at a time, rather than single bytes at a time
(as strcpy() is forced to do).
 
J

Jerry Coffin

[ ... ]
memcpy() might be more efficient because its implementation might be
able to copy entire words at a time, rather than single bytes at a time
(as strcpy() is forced to do).

It's not really forced to do so. At least at one time, Microsoft used
an implementation that scanned for the end, then did the copying in a
separate pass -- and the copying itself was done in 32-bit words.

With a modern CPU, that would probably be a pessimization though --
except under rather special circumstances, anything with a cache will
combine the reads and writes so all transactions with the main memory
happen in cache-line sized chunks (typically substantially larger
than a full word). Such a copy will normally be memory-bound anyway,
so the difference between a really simplistic byte-at-a-time
implementation and a much more complex one that copies entire words
when possible will generally be minuscule.
 
T

Thomas Matthews

Pallav said:
when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
Data Type

Thanks
Pallav

Remember that strcpy will copy until it finds a '\0'.
This could lead to buffer overruns and reading from
undefined places in memory.

strncpy(), notice the 'n', is a lot safer.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
J

Jerry Coffin

Remember that strcpy will copy until it finds a '\0'.
This could lead to buffer overruns and reading from
undefined places in memory.

strncpy(), notice the 'n', is a lot safer.

Despite the similarity in the name, strncpy is quite a bit different
from strcpy, and despite it's "safety", almost nobody ever really
wants what it does.

1) strncpy does NOT zero-terminate the destination string if the
source string is longer than the specified length.
2) If he source is _shorter_ than the specified length, strncpy not
only zero terminates the string, but also zero-fills the entire rest
of the buffer (up to the specified length).

As a result, any time strncpy prevents a buffer overrun, we're still
left with a relatively unsafe condition (a string with no
terminator).

In C++ there's rarely a good reason (or even an excuse) for using any
of the above. Despite its (many) faults, std::string is still clearly
better.
 
J

James Kanze

[ ... ]
memcpy() might be more efficient because its implementation
might be able to copy entire words at a time, rather than
single bytes at a time (as strcpy() is forced to do).
It's not really forced to do so. At least at one time,
Microsoft used an implementation that scanned for the end,
then did the copying in a separate pass -- and the copying
itself was done in 32-bit words.
With a modern CPU, that would probably be a pessimization
though -- except under rather special circumstances, anything
with a cache will combine the reads and writes so all
transactions with the main memory happen in cache-line sized
chunks (typically substantially larger than a full word). Such
a copy will normally be memory-bound anyway, so the difference
between a really simplistic byte-at-a-time implementation and
a much more complex one that copies entire words when possible
will generally be minuscule.

With a modern CPU, the CPU should take care of merging the byte
accesses into word accesses, and copying bytes or words should
not make a significant difference.

With an older CPU, of course, std::copy should be significantly
faster than either, because the compiler can regerate the code
each time it sees the call, taking into account the actual size
and the alignments of the pointers---doing this in memcpy means
you have a lot of extra tests, which slow it down significantly
for small blocks. This is why many compilers actually defined
memcpy and strcpy as macros, expanding to something like
__builtin_memcpy and __builtin_strcpy---the compiler can do a
better job expanding the function each time it is invoked.
 
B

Balog Pal

Yannick Tremblay said:
And any sane programmer will prefer strncpy() over strcpy() for safety
reason unless you do not know the size of the destination.

Only the ignorat ones - strncpy is on the same blacklist strcpy is -- you
shall pick some other, actually well working replacement.
 
B

Balog Pal

Yannick Tremblay said:
Agree, strncpy has a somewhat counter intuitive behaviour. But it is
easy to fix the non-terminated string issue using a single line of
code:

char dest[SOME_SIZE];
dest[SOME_SIZE-1] = 0;
strncpy( buffer, source, sizeof(buffer)-1);

And and even easier fix is to use a fucntion that does what was originally
wanted, instead of patching the wrongly chosen patch, that requires these
extra lines and still hits you filling memory areas not needed in 99.9% of
the cases.

Most compiler environments have good replacement, and it is not hard to
write your own either, that can replace strcpy in the code without much
clatter.
 
J

Juha Nieminen

Jerry said:
Such a copy will normally be memory-bound anyway,
so the difference between a really simplistic byte-at-a-time
implementation and a much more complex one that copies entire words
when possible will generally be minuscule.

I'm not so sure. Copying linear data from one place to another
byte-by-byte requires more raw clock cycles than word-by-word. It's
relatively easy to count how many clock cycles more it would take, in an
optimal situation. Even if the memory/cache chips were somehow able to
optimize consecutive individual byte reads/writes into larger chunks,
the CPU will still perform more operations than when copying entire words.

I don't think CPUs are yet so smart as to merge four consecutive byte
copies (which are performed as four iterations of a loop) into one word
copy. A compiler might be able to do that kind of optimization if it
knows the exact amount of data being copied, but this is certainly not
the case when copying null-terminated strings for which we don't know
the size in advance.
 
J

Jerry Coffin

I'm not so sure. Copying linear data from one place to another
byte-by-byte requires more raw clock cycles than word-by-word. It's
relatively easy to count how many clock cycles more it would take, in an
optimal situation. Even if the memory/cache chips were somehow able to
optimize consecutive individual byte reads/writes into larger chunks,
the CPU will still perform more operations than when copying entire words.

Well, I'll admit I haven't tested it to be sure, but the idea is
pretty simple: yes, the CPU itself is performing more operations --
but the CPU is so much faster than the memory that it should rarely
matter. A typical word is 4 or 8 bytes, but a typical CPU currently
runs with a multiplier of at least 10:1, and often around 15:1.

That means, in essence, that that the CPU itself can do at least 10,
and often around 15 (single-cycle) operations for every memory
transaction, and the overall bandwidth should still be limited by the
memory, not the CPU.

The other side of things is that some CPUs include special hardware
specifically for block moves. I know that on at least some of these
(Intel x86) the special hardware will be used if you do a word-sized
move -- but I'm not sure whether it will if you do a byte-sized move.
If it's not, I'd expect to see a substantial slowdown from that
factor alone.
 
J

Juha Nieminen

Jerry said:
Well, I'll admit I haven't tested it to be sure, but the idea is
pretty simple: yes, the CPU itself is performing more operations --
but the CPU is so much faster than the memory that it should rarely
matter. A typical word is 4 or 8 bytes, but a typical CPU currently
runs with a multiplier of at least 10:1, and often around 15:1.

Which memory are you talking about? Naturally I'm talking about the L1
cache, ie. the fastest memory, closest to the CPU, which is what the CPU
directly accesses.

I have to admit, though, that I'm not completely sure how the speed of
the L1 cache compares to the speed of the CPU, but given that the
machine opcodes being run by the CPU (ie. the actual program being
executed) come from the L1 cache it would seem odd that the CPU would
run 10 times faster than what the cache can feed it. It would sound like
the CPU would be idle for the majority of the time simply because the L1
cache is too slow to feed it more opcodes to run.
 
M

Maxim Yegorushkin

Pallav said:
when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
Data Type

It is quite easy: when you know the length of the source string use memcpy(),
otherwise strlcpy().

Max
 
J

Jerry Coffin

Which memory are you talking about? Naturally I'm talking about the L1
cache, ie. the fastest memory, closest to the CPU, which is what the CPU
directly accesses.

I was thinking in the opposite direction. Copies that stay in the L1
cache are (almost by definition) so small that they rarely matter
enough to notice.

In a lot of cases, however, for a copy you can't deal strictly with
L1 cache. In a fair number of cases (e.g. at least many of Intel's
implementations of x86) the L1 cache is a write-back cache, meaning
all writes go to through to the L2 cache.
I have to admit, though, that I'm not completely sure how the speed of
the L1 cache compares to the speed of the CPU, but given that the
machine opcodes being run by the CPU (ie. the actual program being
executed) come from the L1 cache it would seem odd that the CPU would
run 10 times faster than what the cache can feed it. It would sound like
the CPU would be idle for the majority of the time simply because the L1
cache is too slow to feed it more opcodes to run.

Oh, the caches are definitely closer to the speed of the CPU core --
it's main memory that's substantially slower.
 
J

James Kanze

It is quite easy: when you know the length of the source
string use memcpy(), otherwise strlcpy().

There is no strlcpy in C or C++. There is a proposal for a TR
to C with asafe strcpy_s, but for the moment, it's just a
proposal, and at any rate, it will be a TR, and not part of the
language (so I don't know what C++ will do with it). FWIW: it's
implemented in VC++ (at least with the compiler options I use),
but not in g++ under Linux (again, with the compiler options I
usually use).
 
T

Tech07

James said:
There is no strlcpy in C or C++. There is a proposal for a TR
to C with asafe strcpy_s, but for the moment, it's just a
proposal, and at any rate, it will be a TR, and not part of the
language (so I don't know what C++ will do with it). FWIW: it's
implemented in VC++ (at least with the compiler options I use),
but not in g++ under Linux (again, with the compiler options I
usually use).

That's all maintenance stuff, who cares. Old people bothering young people
with their baggage. Sigh.
 
M

Miles Bader

James Kanze said:
There is a proposal for a TR to C with asafe strcpy_s
FWIW: it's implemented in VC++ (at least with the compiler options I
use), but not in g++ under Linux (again, with the compiler options I
usually use).

That's because "strcpy_s" is a (somewhat ugly) microsoftism,
so naturally VC supports it.

-Miles
 
J

James Kanze

That's because "strcpy_s" is a (somewhat ugly) microsoftism,
so naturally VC supports it.

It's part of a TR being processed by the C standards committee,
which means that it is, or will be, an optional part of standard
C. Certainly not a Microsoftism. From a quality of
implementation point of view, one would expect to find it in any
up to date C compiler.
 
M

Miles Bader

James Kanze said:
It's part of a TR being processed by the C standards committee,
which means that it is, or will be, an optional part of standard
C. Certainly not a Microsoftism.

It is a microsoftism.

Microsoft has proposed it as an addition to the C standard.

-Miles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top