C语言 strcpy_s 如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23307268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:02:43  来源:igfitidea点击:

How does strcpy_s work?

cstringstrcpy

提问by Joey

As we all know, strcpy_s is a safety version of strcpy.

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

But I wonder how it works ...

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

let's see some examples.

让我们看一些例子。

strpy_s's declaration:
errno_t strcpy_s(_CHAR *_DEST, size_t _SIZE, const _CHAR *_SRC)

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

eg1

例如1

char dest[5];
char* src = "abcdefg";
strcpy_s(dest,5,src);

It will return an assertion.
I think I can understand this, use _SIZEto make sure we can't copy more characters than _SIZE

它将返回一个断言。
我想我可以理解这一点,使用_SIZE确保我们不能复制超过_SIZE 的字符

But.. I can't understand this:

但是..我无法理解这一点:

char dest[5];
char* src = "abcdefg";
strcpy_s(dest,10,src);

we can still get a assertion, how did that happened?

我们仍然可以得到断言,这是怎么发生的?

ps,error was:

ps,错误是:

Debug Assertion Failed
expression : (L"Buffer is too small "&&0)

调试断言失败
表达式:(L“缓冲区太小”&&0)


In VS2013


在 VS2013

will strcpy_s checks the size of dest inside its body?? and if it's true , how? how to check a pointer like _DEST?

strcpy_s 会检查它体内 dest 的大小吗??如果是真的,怎么办?如何检查像_DEST这样的指针?

采纳答案by vsoftco

This is actually how to get the size of a stack array at run time without decaying it to a pointer:

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

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

You send it as a template reference, and the template mechanism deduces the size. So, you can do something like

您将其作为模板引用发送,模板机制会推断出大小。所以,你可以做类似的事情

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

So my guess is that this is how the "safe" MS strcpy_sis checking the sizes. Otherwise, if you pass just a pointer, there is NO STANDARD-COMPLIANT way of getting the size.

所以我的猜测是,这就是“安全”MSstrcpy_s检查尺寸的方式。否则,如果您只传递一个指针,则没有获取大小的标准方法。

回答by Ananké

In DEBUG mode, MicroSoft APIs fill the buffer with 0xfd, so they can check for an overflow.

在调试模式下,MicroSoft API 用 0xfd 填充缓冲区,以便它们可以检查溢出。

This function doesn't truncate the copied string, but raises an exception!

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

It's always a pain to specify the size of the dest buffer (use _countof rather than sizeof), mostly when you use a pointer!

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

I have more problems with those "_s" APIs than with the standards ones!!

我对那些“_s”API 的问题比标准 API 的问题要多!!

回答by vsoftco

destcannot hold more than 5 chars, that's why you get the error. It is not because of _SIZE. If destwas char*then you need to make sure you allocate enough memory for it, you won't get any compile error. But in your program desthas a fixed size, and strcpy_s, unlike strcpy, checks the size of the destination buffer (if it can, and in this case it can as its size is defined at compile time). Read this

dest不能容纳超过 5 个字符,这就是您收到错误的原因。这不是因为_SIZE. 如果dest是,char*那么您需要确保为其分配足够的内存,您将不会收到任何编译错误。但是在您的程序中dest具有固定大小,并且strcpy_s与 不同strcpy,检查目标缓冲区的大小(如果可以,在这种情况下它可以因为它的大小在编译时定义)。读这个

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

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

Basically strcpy_sis the "safe" version of strcpy, it doesn't allow you to overflow. From the standard: C (2011) and ISO/IEC WDTR 24731 - strcpy_s: a variant of strcpythat checks the destination buffer size before copying. Internally, probably strcpy_sasserts sizeof(dest)<SIZE.

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

回答by Santosh Dhanawade

MSDNSays "The strcpy_s function copies the contents in the address of strSource, including the terminating null character, to the location that's specified by strDestination. The destination string must be large enough to hold the source string and its terminating null character. The behavior of strcpy_s is undefined if the source and destination strings overlap."

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