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 。 如果destchar*那么你需要确保为它分配足够的内存,你不会得到任何编译错误。 但是在你的程序中, dest有一个固定的大小,而strcpystrcpy不同,它检查目标缓冲区的大小(如果可以,在这种情况下,它可以在编译时定义它的大小)。 读这个

http://www.cplusplus.com/forum/beginner/118771/

基本上strcpy_sstrcpy的“安全”版本,它不允许你溢出。 从标准:C(2011)和ISO / IEC WDTR 24731 – strcpy_sstrcpy的变体,它在复制之前检查目标缓冲区大小。 在内部, strcpy_s可能断言sizeof(dest)

MSDN表示“strcpy_s函数将strSource地址中的内容(包括终止空字符)复制到strDestination指定的位置。 目标字符串必须足够大以容纳源字符串及其终止空字符 。如果源和目标字符串重叠,strcpy_s是未定义的。“