在Visual Studio中strcpy_s的意外行为

huangapple go评论132阅读模式
英文:

An unexpected behavior of strcpy_s in Visual Studio

问题

strcpy_s is a safer version of the strcpy function in C/C++. It is used to copy a string from one character array to another while ensuring that the destination array doesn't overflow. The -2 you are seeing in the safe array likely comes from the fact that strcpy_s includes a buffer size check to prevent buffer overflows. When strcpy_s encounters a buffer overflow, it doesn't proceed with the copy and instead returns an error code of -2.

In your code, you are using strcpy_s with a destination buffer size of 10 characters, but the source string (ori) is longer than that. It contains the characters 'a', 'b', '\0', 'c', and 'd', which is 5 characters. When you use strcpy_s to copy ori into safe, it detects that the source string is too long for the destination buffer, and that's why you get the -2 as an error code.

On the other hand, strcpy does not have this safety check, so it doesn't prevent buffer overflows. When you use strcpy to copy ori into unsafe, it doesn't check the buffer size, and as a result, it may overwrite memory beyond the bounds of the unsafe array, which can lead to unexpected behavior or crashes.

英文:

Platform: Win11, VisualStudio 2022
Code:

#include <stdio.h>
#include <string.h>

int main()
{
    char ori[5] = { 'a', 'b', '
#include <stdio.h>
#include <string.h>
int main()
{
char ori[5] = { 'a', 'b', '\0', 'c', 'd' };
//char *safe = malloc(10 * sizeof(char));
//char *unsafe = malloc(10 * sizeof(char));
char safe[10];
char unsafe[10];
memset(safe, 0, 10 * sizeof(char));
memset(unsafe, 0, 10 * sizeof(char));
strcpy(unsafe, ori);
strcpy_s(safe, 10, ori);
printf("SAFE: %c\n", safe[3]);
printf("UnSafe: %c\n", unsafe[3]);
return 0;
}
', 'c', 'd' }; //char *safe = malloc(10 * sizeof(char)); //char *unsafe = malloc(10 * sizeof(char)); char safe[10]; char unsafe[10]; memset(safe, 0, 10 * sizeof(char)); memset(unsafe, 0, 10 * sizeof(char)); strcpy(unsafe, ori); strcpy_s(safe, 10, ori); printf("SAFE: %c\n", safe[3]); printf("UnSafe: %c\n", unsafe[3]); return 0; }

I have two arrays, safe and unsafe. After memset, both of them are initialized as {0,0,0,0,0,0,0,0,0,0} (showing characters as integers).

After strcpy and strcpy_s, I expect to get {'a','b','\0','\0','\0','\0','\0','\0','\0','\0'} in both the safe and unsafe arrays. However, in safe, I obtained {97,98,0,-2,-2,-2,-2,-2,-2,-2} (showing characters as integers).

What does strcpy_s do, and where does the -2 come from?

答案1

得分: 6

official Microsoft documentation for the function strcpy_s 指出以下信息:

> 这些函数的调试库版本首先使用 0xFE 填充缓冲区。要禁用此行为,请使用 _CrtSetDebugFillThreshold。

如果将 0xFE 转换为 signed char,您会得到值 -2

英文:

The official Microsoft documentation for the function strcpy_s states the following:

> The debug library versions of these functions first fill the buffer with 0xFE. To disable this behavior, use _CrtSetDebugFillThreshold.

If you convert 0xFE to a signed char, you get the value -2.

答案2

得分: 3

Writing -2 is allowed by the C specification.

errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);

strcpy_s 在由 s1 指向的长度为 s1max 字符的数组中写入终止空字符(如果有的话)后,strcpy_s 返回时,s1 指向的数组中终止空字符后的所有元素的值都是未指定的。C17dr § K.3.7.1.3 4

这适用于无论任何调试设置或使用的编译器。

代码不应依赖于终止空字符之后的字节保持不变。

英文:

Writing -2 is allowed by the C specification.

errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2);

> All elements following the terminating null character (if any) written by strcpy_s in the array of s1max characters pointed to by s1 take unspecified values when strcpy_s returns. C17dr § K.3.7.1.3 4

This applies regardless of any debug setting or compiler used.
Code should not rely on bytes past the null character to remain unchanged.

huangapple
  • 本文由 发表于 2023年6月29日 09:40:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577579.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定