strcpy_s如何工作?
众所周知,strcpy_s是strcpy的安全版本。
但我想知道它是如何工作的……
让我们看一些例子。
strpy_s的声明:
errno_t strcpy_s(_CHAR * _DEST,size_t _SIZE,const _CHAR * _SRC)
[点拨
char dest[5]; char* src = "abcdefg"; strcpy_s(dest,5,src);
它将返回一个断言。
我想我能理解这一点,使用_SIZE确保我们不能复制比_SIZE更多的字符
但是……我无法理解这一点:
char dest[5]; char* src = "abcdefg"; strcpy_s(dest,10,src);
我们仍然可以得到一个断言,那是怎么发生的?
ps,错误是:
调试断言失败
表达式:(L“缓冲区太小”&& 0)
在VS2013中
strcpy_s会检查其体内dest的大小吗? 如果这是真的,怎么样? 如何检查像_DEST这样的指针?
这实际上是如何在运行时获取堆栈数组的大小而不将其衰减为指针:
template size_t arrSize(T (&array)[N]) { return N; }
您将其作为模板引用发送,模板机制推断出大小。 所以,你可以做点什么
int myArray[10]; cout << arrSize(myArray); // will display 10
所以我的猜测是这就是“安全”MS strcpy_s
检查大小的方式。 否则,如果你只传递一个指针,那么就没有STANDARD-COMPLIANT方法来获取大小。
在DEBUG模式下,MicroSoft API使用0xfd填充缓冲区,因此可以检查溢出。
此函数不会截断复制的字符串,但会引发exception!
指定dest缓冲区的大小总是很痛苦(使用_countof而不是sizeof),主要是在使用指针时!
我对那些“_s”API的问题比标准的问题多!
dest
不能超过5个字符,这就是你得到错误的原因。 这不是因为_SIZE
。 如果dest
是char*
那么你需要确保为它分配足够的内存,你不会得到任何编译错误。 但是在你的程序中, dest
有一个固定的大小,而strcpy
与strcpy
不同,它检查目标缓冲区的大小(如果可以,在这种情况下,它可以在编译时定义它的大小)。 读这个
http://www.cplusplus.com/forum/beginner/118771/
基本上strcpy_s
是strcpy
的“安全”版本,它不允许你溢出。 从标准:C(2011)和ISO / IEC WDTR 24731 – strcpy_s
: strcpy
的变体,它在复制之前检查目标缓冲区大小。 在内部, strcpy_s
可能断言sizeof(dest)
MSDN表示“strcpy_s函数将strSource地址中的内容(包括终止空字符)复制到strDestination指定的位置。 目标字符串必须足够大以容纳源字符串及其终止空字符 。如果源和目标字符串重叠,strcpy_s是未定义的。“