众所周知,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);
Run Code Online (Sandbox Code Playgroud)
它将返回一个断言.
我想我能理解这一点,使用_SIZE确保我们不能复制比_SIZE更多的字符
但是......我无法理解这一点:
char dest[5];
char* src = "abcdefg";
strcpy_s(dest,10,src);
Run Code Online (Sandbox Code Playgroud)
我们仍然可以得到一个断言,那是怎么发生的?
ps,错误是:
Debug Assertion Failed
表达式:(L"Buffer is too small"&& 0)
在VS2013中
strcpy_s会检查其体内dest的大小吗?如果这是真的,怎么样?如何检查像_DEST这样的指针?
这实际上是如何在运行时获取堆栈数组的大小而不将其衰减为指针:
template<typename T, size_t N>
size_t arrSize(T (&array)[N])
{
return N;
}
Run Code Online (Sandbox Code Playgroud)
您将其作为模板引用发送,模板机制推断出大小.所以,你可以做点什么
int myArray[10];
cout << arrSize(myArray); // will display 10
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是这就是"安全"MS strcpy_s
检查尺寸的方式.否则,如果你只传递一个指针,那么就没有STANDARD-COMPLIANT方法来获取大小.
小智 7
在调试模式下,MicroSoft API 用 0xfd 填充缓冲区,以便它们可以检查溢出。
该函数不会截断复制的字符串,但会引发异常!
指定目标缓冲区的大小(使用 _countof 而不是 sizeof)总是很痛苦,尤其是当您使用指针时!
我对这些“_s”API 的问题比标准 API 的问题还要多!