测试如下代码:
#include
using namespace std;
int main(){
char a[] = "123456789";
char b[] = "123";
cout<
cout<
}
AND
int main(){
char a[] =
"123456789";
char b[] = "123";
cout<
cout<
}
第一段程序输出 123 \n 0 ;这是因为 strcpy的原型是
_char * _cdecl strcpy(char *_Dest ,const char * _Source)返回一个char *
,可能是为了链接使用的方便性:
如:
char s1[20]
,s2[20];
strcpy(s1,strcpy(s2,"just a
test"));
而strcpy_s是C++做的扩展的一个CRT函数,它的原型....
查看定义 :
__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(errno_t, strcpy_s,
_Deref_post_z_ char, _Dest, _In_z_ const char *, _Source)
__DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1 是一个宏
它的定义如下:
#define __DEFINE_CPP_OVERLOAD_SECURE_FUNC_0_1(_ReturnType,
_FuncName, _DstType, _Dst, _TType1, _TArg1) \
extern "C++" \
//按C++规则编译
{ \
template \
inline \
_ReturnType __CRTDECL
_FuncName(_DstType (&_Dst)[_Size], _TType1 _TArg1)
_CRT_SECURE_CPP_NOTHROW \
{ \
return _FuncName(_Dst, _Size, _TArg1); \
} \
}
//说明:
'\' 是续行符,一般在宏定义中使用,因为宏定义只允许使用一行不能换行.(为什么这么规定?)
由strcpy_s的声明可见:
他的函数原型是: errno_t
strcpy_s<4U>(char (&Dest)[4U], const char * Source)
这是一个模板函数 返回一个errno_t (typedef int errno_t)
两个函数的区别是:
第一,返回类型不同;
第二,对于错误处理的特点不同:
strcpy在第二代码中可以将原字符串输出,但程序结束因缓冲区溢出而崩溃;而strcpy_s执行时先检测空间内存是否满足拷贝的条件,不足则抛出异常,不执行拷贝操作.
下面摘抄一段MSDN关于strcpy_s的说明:
Some of the security enhancements are:
Parameter Validation. Parameters passed to CRT
functions are validated, in both secure functions and in many
preexisting versions of functions. These validations include:
Checking
for NULL values
passed to the functions,
Checking enumerated values for validity,
Checking that integral values are in valid ranges.
For more information, see Parameter Validation.
There is also a handler for invalid parameters which is accessible
to the developer. When an invalid parameter is encountered, instead
of asserting and exiting the application, the CRT provides a way to
check these problems with the _set_invalid_parameter_handler
function.
Sized Buffers. The secure functions require that
the buffer size be passed to any function that writes to a buffer.
The secure versions validate that the buffer is large enough before
writing to it, helping to avoid dangerous buffer overrun errors
which could allow malicious code to execute. These functions will
usually return
an errno type of
error code and invoke the invalid parameter handler if the size of
the buffer is too small. Functions which read from input buffers,
such as gets, have secure
versions that require you to specify a maximum size.
Null termination. Some functions which left
potentially non terminated strings have secure versions which
ensure that strings are properly null terminated.
Enhanced error reporting. The
secure functions return error codes with more error information
than was available with the preexisting functions. The secure
functions and many of the preexisting functions now
set errno and
often return
an errno code
type as well, to provide better error reporting.
Filesystem security. Secure file
I/O APIs support secure file access in the default case.
Windows security. Secure process
APIs enforce security policies and allow ACLs to be specified.
Format string syntax
checking. Invalid strings are now
detected, for example using incorrect type field characters
inprintf format
strings.
Additional security enhancements are described in the documentation
for each function.