Difference between strcpy() and strcat()?

P

Pascal Damian

I read somewhere that strcpy() is safer when dealing with malloc()-ed
strings. Is that true?

(Of course I know that both are unsafe).
 
J

Jens.Toerring

Pascal Damian said:
I read somewhere that strcpy() is safer when dealing with malloc()-ed
strings. Is that true?
(Of course I know that both are unsafe).

This question is like: "I read somewhere that handling sodium instead
of potassium is safer in a humid enviroment. Is that true?"

They do different things. Use strcpy() if you want to copy a string and
strcat() when you need to append a string to another one. Of course,
you can use strcpy() instead of strcat() if you want (and don't mind
the time needed for an additional function call to find the end of
the first string) but there is no additional inherent safety in using
one or the other.
Regards, Jens
 
L

Leor Zolman

I read somewhere that strcpy() is safer when dealing with malloc()-ed
strings. Is that true?

(Of course I know that both are unsafe).

I've not read anything to that effect, but I can easily imagine someone,
somewhere having at some point said something like:

"strcpy is safer than strcat because it is easier to check programmatically
that a strcpy operation will not overflow the buffer: presumably you know
the length of your destination buffer, so all you have to do is check the
length of the source string. With strcat, on the other hand, you have to
test the length of the existing string in the buffer, add the length of the
string to be appended, and make sure the total resulting length is going to
fit into your available space."

But that would actually be rubbish...I've probably had more overruns with
functions like strcpy than with strcat. Why? Because I've been more
/careful/ while using strcat... ;-)
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
M

Mik Mifflin

Of course,
you can use strcpy() instead of strcat() if you want (and don't mind
the time needed for an additional function call to find the end of
the first string) but there is no additional inherent safety in using
one or the other.
Regards, Jens

And strcat doesn't need to find the end of the first string?

I only use strcpy when I've just allocated enough space for the string, or I
keep a close eye on the buffer sizes and I know it's not going to overflow.
In all other places, I use strncpy and strncat.
 
R

Richard Bos

Mik Mifflin said:
And strcat doesn't need to find the end of the first string?

Yes, but it may be able to do so more efficiently. For one thing,
strlen() followed by strcpy() is two function calls, strcat() only one.
No guarantees, of course (the Standard doesn't guarantee _anything_
where efficiency is concerned), but I know where I'd put my money.
I only use strcpy when I've just allocated enough space for the string, or I
keep a close eye on the buffer sizes and I know it's not going to overflow.
In all other places, I use strncpy and strncat.

Don't use strncpy() unless you know exactly why it is usually
inadvisable to use strncpy(). Use *dest='\0'; strncat(); instead.

Richard
 
N

nrk

Richard said:
Yes, but it may be able to do so more efficiently. For one thing,
strlen() followed by strcpy() is two function calls, strcat() only one.
No guarantees, of course (the Standard doesn't guarantee _anything_
where efficiency is concerned), but I know where I'd put my money.


Don't use strncpy() unless you know exactly why it is usually
inadvisable to use strncpy(). Use *dest='\0'; strncat(); instead.

This is silly advice. strncpy is perfectly usable and safe as long as you
understand what it is supposed to do. There may be performance reasons to
avoid strncpy, but any other reason is unnecessary paranoia. If you're not
careful when you program in C, you'll get burnt, regardless of how many
library functions you assiduously avoid. I am not sure why everyone gets
worked up about strncpy possibly not null terminating the string. It is
quite straight forward to check if it has done so or not. If you blindly
substitute strncat for strncpy you'll be in for some surprises as strncat
may write n+1 characters and not n.

-nrk.
 
P

Pascal Damian

Leor Zolman said:
that a strcpy operation will not overflow the buffer: presumably you know
the length of your destination buffer, so all you have to do is check the
length of the source string. With strcat, on the other hand, you have to
test the length of the existing string in the buffer, add the length of the
string to be appended, and make sure the total resulting length is going to
fit into your available space."

But that would actually be rubbish...I've probably had more overruns with
functions like strcpy than with strcat. Why? Because I've been more
/careful/ while using strcat... ;-)

To Jens,

Yes, sorry. The question should be: "what's the difference between
using strcat() or strcpy() to append a string?"

To Leor,

Here's exactly where I read it, from a post at comp.lang.ruby:

======================== start quote ============================
p = (char *)getenv("LD_LIBRARY_PATH");

Use strcpy instead of strcat here, content of malloc'ed area is
not guaranteed.
======================== end quote ============================

URL: http://groups.google.com/[email protected]
URL: http://tinyurl.com/393yz

Now what does the poster mean by "content of malloc'ed area is not
guaranteed"?
 
J

Jens.Toerring

Pascal Damian said:
Here's exactly where I read it, from a post at comp.lang.ruby:
======================== start quote ============================
Use strcpy instead of strcat here, content of malloc'ed area is
not guaranteed.
======================== end quote ============================
Now what does the poster mean by "content of malloc'ed area is not
guaranteed"?

strcat() appends to a '\0'-terminated string (first searching for
that value to figure out where to write to), but the malloc()-ed
memory isn't initialized. While there may be a `\0' somewhere in
that memory just by chance, there's no guarantee that the first
char of the memory is '\0'. But that would be the requirement if
you want to use strcat() instead of strcpy(). So the author of
that article is just pointing out a bug in the logic of the code
- most likely the string "LD_LIBRARY_PATH=" is going to be written
to some random location in memory, possibly outside the malloc()-ed
area. If you insist on using strcat() in this case you would need
set the first char in the memory to '\0' first (or use calloc() to
obtain the memory).
Regards, Jens
 
L

Leor Zolman

Here's exactly where I read it, from a post at comp.lang.ruby:

======================== start quote ============================

Use strcpy instead of strcat here, content of malloc'ed area is
not guaranteed.
======================== end quote ============================

URL: http://groups.google.com/[email protected]
URL: http://tinyurl.com/393yz

Now what does the poster mean by "content of malloc'ed area is not
guaranteed"?

Along with what Jens said, I think this kinda goes along with what I was
saying. There's more "stuff" to think about when using strcat; Personally,
I would never dream of using it "in place of" strcpy; the question just
wouldn't arise because I'm totally acclimated to what each of them does and
would pick the one most suitable to the task in the first place [and this
would probably be the wrong group to mention that, these days, I'd use
std::string in C++ and try to avoid str*() whenever possible, so I won't
say it... ;-) ]. The question isn't "which one is safer"; the lesson is:
research well what /any/ function does before you use it!
-leor

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
P

Pascal Damian

strcat() appends to a '\0'-terminated string (first searching for
that value to figure out where to write to), but the malloc()-ed
memory isn't initialized. While there may be a `\0' somewhere in
that memory just by chance, there's no guarantee that the first
char of the memory is '\0'. But that would be the requirement if
you want to use strcat() instead of strcpy(). So the author of
that article is just pointing out a bug in the logic of the code
- most likely the string "LD_LIBRARY_PATH=" is going to be written
to some random location in memory, possibly outside the malloc()-ed
area. If you insist on using strcat() in this case you would need
set the first char in the memory to '\0' first (or use calloc() to
obtain the memory).

Of course. I did remember this from years, years back. Thanks for the
verbose and clear explanation.
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top