Thanks
Pallav
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.
--
Richard Herring
>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.
--
Tim Slattery
Slatt...@bls.gov
http://members.cox.net/slatteryt
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).
[ ... ]
> 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.
--
Later,
Jerry.
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
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.
--
Later,
Jerry.
> [ ... ]
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.
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
And any sane programmer will prefer strncpy() over strcpy() for safety
reason unless you do not know the size of the destination.
Of course, since this is a C++ newsgroup, strcpy and strncpy have
little reasons to be used. Prefer std::string. memcpy is probably
better replaced by std::copy()
Yan
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);
Annoying that they did not include it internally in strncpy but not a
justification to use the unsafe strcpy.
As for the filling with nulls... yeah, it might have a very very minor
performance impact but avoiding strncpy because of that would be a
very bad case of premature optimisation.
>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.
Absolutely in agreement.
Yan
Only the ignorat ones - strncpy is on the same blacklist strcpy is -- you
shall pick some other, actually well working replacement.
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.
Agree. But then again since we are talking about C++, str(n)cpy
should hardly be used at all. There are better thing than '\0'
terminated contiguous memory buffer to use for strings.
>extra lines and still hits you filling memory areas not needed in 99.9% of
>the cases.
As I mentionned, what is the problem with the zero filling? Have you
*measured* that this has a negative effect of your application?
>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.
If you are writing multiplatform code, you can't use a compiler
specific one.
Yan
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.
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.
--
Later,
Jerry.
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.
strncpy() is not safer.
It is the only C string function which may not '\0' terminate
For that reason, it is positively unsafe.
It is also inefficient. Unlike the other strnxxx() functions, it
always writes n characters to the destination even if the source
string is shorter.
For
strncpy(dest, src, n);
I substitute the following stylized code
dest[0] = '\0';
strncat(dest, src, n);
with the right buffer sizes.
That is both safe and efficient.
On my list of C functions that I do not use are
gets() - you cannot use this safely. Use fgets()
scanf() - uncontrollable. user can type anything.
Use fgets() and sscanf() or own parsing.
strncpy() - as above. Use strncat().
Also
strtok() - poor performance in mutithreaded code
(must use tls to save state)
I still use strcpy(), memcpy() which are fine providing you make sure
that code that calls these has done the right buffer checks.
I dont recall ever having a buffer overrun.
Stephen Howe
A trivial test of memcpy vs strcpy vs strncpy for various string
length on Linux x86 with g++ seems to indicate memcpy being slower for
very short string (less than 20 bytes, memcpy appears to have a fixed cost
regardless of length), once you reach 20-30 bytes, strcpy becomes
slower. strncpy is always a bit slower than strcpy. At 120 bytes,
memcpy is about 4x faster than strcpy.
Of course these figures might not be relevant for an application.
Yan
man strtok:
BUGS
Avoid using these functions. If you do use them, note that:
These functions modify their first argument.
These functions cannot be used on constant strings.
The identity of the delimiting character
It is quite easy: when you know the length of the source string use memcpy(),
otherwise strlcpy().
Max
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.
--
Later,
Jerry.
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.
That's because "strcpy_s" is a (somewhat ugly) microsoftism,
so naturally VC supports it.
-Miles
--
[|nurgle|] ddt- demonic? so quake will have an evil kinda setting? one that
will make every christian in the world foamm at the mouth?
[iddt] nurg, that's the goal
> 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.
It is a microsoftism.
Microsoft has proposed it as an addition to the C standard.
-Miles
--
Innards, n. pl. The stomach, heart, soul, and other bowels.
Really? Considering Microsoft doesn't even support C99, that's a bit rich!
--
Ian Collins
nonsense! strncpy() has all sorts of odd behaviour
> when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
> Data Type
more the semantics (meaning) of the data. Use strcpy() to copy
a C-string and memcpy() to copy a block of memory of known size.
In a C++ program (and you are posting on comp.lang.c++) you should
only very rarely be using C-strings. Use C++ strings and just assign
them.
--
Nick Keighley
In what sense. It is surprising that they support this, I
agree. But it's very much a part of C, and it's even more
surprising that serious C compilers don't support it. (On the
other hand, there are some serious C++ compilers which don't
support export, and that's fully a part of the standard. In the
end, I gather that most compiler vendors don't really give a
damn about the standard, and just support whatever they feel
like.)
> It is a microsoftism.
> Microsoft has proposed it as an addition to the C standard.
Whoever proposed it, it's now being handled by the C standard
committee, which means that it has official status in the
language.
All sorts?
Undesirable behaviour that should have been done correctly:
1- Does not '\0' terminate the destination string if the source string
is longer than n.
Arguable behaviour that has benefits and drawbacks:
1- pads the destination string with '\0' up to n.
> It is surprising that they support this, I
> agree. But it's very much a part of C, and it's even more
> surprising that serious C compilers don't support it.
Where is it defined as part of C?
Not in the C99 standard or the latest C1x draft.
--
Ian Collins
those aren't what I'd call "bugs". They are simply what the function
does.
> The identity of the delimiting character
what about it?
Actually what i don't like about strtok() is how it handles empty
fields
red,blue,,green
That's actually a direct copy-paste from the man page of strtok.
Whoeverwrote that man page classified them as bugs.
>> � � � � � � � The identity of the delimiting character
>
>what about it?
Oops, sorry, that a copy-paste truncating... Here's the full section:
-------------------------------------------------------------------
BUGS
Avoid using these functions. If you do use them, note that:
These functions modify their first argument.
These functions cannot be used on constant strings.
The identity of the delimiting character is lost.
The strtok() function uses a static buffer while
parsing, so it's not thread safe. Use strtok_r() if this matters to
you.
-------------------------------------------------------------------
>
>Actually what i don't like about strtok() is how it handles empty
>fields
>
>red,blue,,green
There's very little I like about strtok... apart from the man page :-)
Yannick
It will be defined in a TR.
> Not in the C99 standard or the latest C1x draft.
TR's aren't directly incorporated in the standard; they're
optional extensions. But such extensions are as much a part of
C as things like tr::array are a part of C++.