英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论