Re: strcpy_s vs strcpy
On Jul 2, 3:33 pm, Trups <Samant.Tru...@gmail.com> wrote:
Hi,
I have changed my strcpy to strcpy_s for 2005 project. It's fairly
big project and was using strycpy lot of places.
The program started corrupting the stack and in turn crashing the
application. We have realized that it is due to strcpy_s. We have
changes that to strpcy and then it was fine.
But is there any known problem with strcpy_s?
To begin with, strcpy_s is not a part of ISO C++. At present, it is a
proprietary library extension, though it is being standardized as ISO/
IEC TR 24731 - but that is in draft status at present, and, at any
rate, is a TR for ISO C rather than ISO C++. Having said that...
There are some places the destlength was more then whatever size of
deststr. I know it is a mistake but the copy string had character to
copy.
The whole point of strcpy_s is to check for buffer overflow. It cannot
do that if you give it the wrong size of the destination buffer. If
that happens, and you pass a source string that does not fit in the
destination buffer (and strcpy_s won't catch that because you lied
about the size of the buffer), you will get a stack overflow for sure
- but you will get that with strcpy, as well. There are no reasons to
ever lie about the size of destination buffer, period.
So I was thinking it shouldn't crash the project. Isn't that true?
Example:
deststr[128];
copystr[] = "Test String";
destlength = 256;
strcpy_s(deststr, destlength, copystr);
even strcpy_s(deststr, strlen(copystr), copystr); was crashing (I need
to look more for this)
The reason why it happens is that, most likely, you compile it in
debug mode. Microsoft implementation does a simple sanity check on the
destination buffer, described in MSDN as follows:
"The debug versions of these functions first fill the buffer with
0xFD."
Of course, it uses the buffer length that you pass to it to do so.
Since you've passed it a wrong one, you've got a stack overflow.
In short, don't try to make guesses about when breaking a declared
function contract might be okay, based on possible implementation
details - you may always guess wrong, such as in this case.
To give another example in the same vein, consider this code:
{
std::vector<int> v; // 0 elements
int& i = v[0]; // get reference to 1st element, but never use it;
U.B.
}
Technically, the second line there is U.B., but you might think that
it's okay because you won't get any problems until you actually try to
read or write something via the reference, and if you never do it,
then it's not an error. But most debugging STL implementations
(including Microsoft's) will in fact do a check on operator[] when
running in STL debugging mode, and report it as error straight away,
dereference or not. You can try it on MSVC8 or higher and see for
yourself.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]