tags:

views:

147

answers:

4

I am getting warning when using the std copy function.

I have a byte array that I declare.

byte *tstArray = new tstArray[length];

Then I have a couple other byte arrays that are declared and initialized with some hex values that i would like to use depending on some initial user input.

I have a series of if statements that I use to basically parse out the original input, and based on some string, I choose which byte array to use and in doing so copy the results to the original tstArray.

For example:

if(substr1 == "15")
{
   std::cout<<"Using byte array rated 15"<<std::endl;
   std::copy(ratedArray15,ratedArray15+length,tstArray);
} 

The warning i get is warning C4996: 'std::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct.

A possible solution is to to disable this warning is by useing -D_SCL_SECURE_NO_WARNINGS, I think. Well, that is what I am researching.

But, I am not sure if this means that my code is really unsafe and I actually needed to do some checking?

+2  A: 

Basically, what this warning tells you is that you have to be absolutely sure that tstArray points to an array that is large enough to hold "length" elements, as std::copy does not check that

Éric Malenfant
+2  A: 

C4996 means you're using a function that was marked as __declspec(deprecated). Probably using D_SCL_SECURE_NO_WARNINGS will just #ifdef out the deprecation. You could go read the header file to know for sure.

But the question is why is it deprecated? MSDN doesn't seem to say anything about it on the std::copy() page, but I may be looking at the wrong one. Typically this was done for all "unsafe string manipulation functions" during the great security push of XPSP2. Since you aren't passing the length of your destination buffer to std::copy, if you try to write too much data to it it will happily write past the end of the buffer.

To say whether or not your usage is unsafe would require us to review your entire code. Usually there is a safer version they recommend when they deprecate a function in this manner. You could just copy the strings in some other way. This article seems to go in depth. They seem to imply you should be using a std::checked_array_iterator instead of a regular OutputIterator.

Something like:

stdext::checked_array_iterator<char *> chkd_test_array(tstArray, length);
std::copy(ratedArray15, ratedArray15+length, chkd_test_array);

(If I understand your code right.)

jeffamaphone
`checked_array_iterator` is not std, though.
UncleBens
Yeah, stdext is not a fun land to play in. However, the deprecation isn't standard either. Personally I've never had the need to use std::copy() for character arrays; I prefer instead to use StringCchCopy(), though that is also Microsoft specific. In portable code I would write a wrapper that uses strncpy() on non-MSFT platforms.
jeffamaphone
this was most helpful. the only thing that has me a little puzzled is that when i go to http://msdn.microsoft.com/en-us/library/aa985928(VS.80).aspx and for the length use _count(array_name) then i get an error that saysCompiler Error C2784'declaration' : could not deduce template argument for 'type' from 'type'The compiler cannot determine a template argument from the supplied function arguments.but when i use the exact array size which in this case i do know then it works just fine. any ideas? other than that it was most helpful.
djones2010
on other comment, if i will be shipping this code out to another windows env will it be a problem for me to use soemthing other than std?? so far i have been just using that since it usually provides the least amount of problems.
djones2010
Templates make my head explode. If you want to know the size of an array, use the ARRAY_SIZE() (but that only works on arrays, not pointers so you can't use it on char*s).
jeffamaphone
stdext:: only exists on Windows, so yeah, you'll have problems compiling on non-Windows platforms.
jeffamaphone
+1  A: 

Well, I assume Microsoft's unilateral deprecation of the stdlib also includes passing char* to std::copy. (They've messed with a whole range of functions actually.)

I suppose parts of it has some merit (fopen() touches global ERRNO, so it's not thread-safe) but other decisions do not seem very rational. (I'd say they took a too big swathe at the whole thing. There should be levels, such as non-threadsafe, non-checkable, etc)

I'd recommend reading the MS-doc on each function if you want to know the issues about each case though, it's pretty well documented why each function has that warning, and the cause is usually different in each case.

Marcus Lindblom
A: 

At least it seems that VC++ 2010 RC does not emit that warning at the default warning level.

Nemanja Trifunovic
Ignoring the warning is not a solution. You should, at the very least, understand why the warning is occurring before you decide to ignore it.
jeffamaphone
I am not ignoring it - I am simply saying VC++ 2010 RC does not emit it anymore.
Nemanja Trifunovic