strcpy_s如何工作?

时间:2014-04-26 05:58:17

标签: c string strcpy

众所周知,strcpy_s是strcpy的安全版本。

但我想知道它是如何运作的......

让我们看一些例子。

strpy_s的声明:
errno_t strcpy_s(_CHAR * _DEST,size_t _SIZE,const _CHAR * _SRC)

EG1

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这样的指针?

4 个答案:

答案 0 :(得分:8)

这实际上是如何在运行时获取堆栈数组的大小而不将其衰减为指针:

template<typename T, size_t N> 
size_t arrSize(T (&array)[N])  
{
  return N;
}

您将其作为模板参考发送,模板机制会推断出尺寸。所以,你可以做类似

的事情
int myArray[10];
cout << arrSize(myArray); // will display 10

所以我猜这就是&#34;安全&#34; MS strcpy_s正在检查尺寸。否则,如果你只传递一个指针,就没有标准的顺应方式来获取大小。

答案 1 :(得分:2)

在DEBUG模式下,MicroSoft API使用0xfd填充缓冲区,因此可以检查溢出。

此函数不会截断复制的字符串,但会引发异常!

指定dest缓冲区的大小总是很痛苦(使用_countof而不是sizeof),主要是在使用指针时!

我对那些“_s”API比使用标准API有更多问题!!

答案 2 :(得分:1)

dest不能超过5个字符,这就是您收到错误的原因。这不是因为_SIZE。如果destchar*,那么您需要确保为其分配足够的内存,否则不会出现任何编译错误。但是在你的程序dest中有一个固定的大小,strcpy_sstrcpy不同,检查目标缓冲区的大小(如果可以的话,在这种情况下,它的大小可以是在编译时定义)。 阅读本文

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

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

答案 3 :(得分:1)

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