字符串复制说缓冲区太小,strcpy_s 源问题
String copy is saying buffer is too small, strcpy_s source issue
我很困惑,如果这很明显,我很抱歉,但是:
int main()
{
char stringDest[20];
char stringSource[20];
strcpy_s(stringDest, stringSource);
return 0;
}
抛出异常 "Buffer is too small"。鉴于:
char stringSource[20];
int main()
{
char stringDest[20];
strcpy_s(stringDest, stringSource);
return 0;
}
工作正常。
此外,我认为保险箱的要点 strcpy_s(dest, size, source)
是您指定要复制的字节数,但是当我这样做时:
int main()
{
char stringDest[20];
char stringSource[20];
strcpy_s(stringDest, 1, stringSource);
return 0;
}
我得到一个 "Buffer is too small exception"。
我感到很困惑。为什么在 main()
之外声明变量会有所不同?为什么指定 1 个字节进行复制是错误的?
你在这里调用了未定义的行为,因为你没有初始化源字符串。
在大多数情况下,会有垃圾,第一个0
字节很可能在长度为20之后,这就是compiler/runtime抱怨的原因。
char stringSource[20] = {0};
或者
char stringSource[20] = "";
最合适的。
根据您的环境,在调试版本中,编译器可以有意地用 0xff
之类的值填充变量,以便第一个 0-byte
始终超出限制。
如果将 char stringDest[20]
放在函数外部,它将成为一个全局变量,CRT 启动时始终将其初始化为 0
。
在你的最后一个例子中,你应该看看 strcpy_s 的描述。
如果
,此变体将导致错误
destsz is less or equal strnlen_s(src, destsz); in other words, truncation would occur
strcpy_s(stringDest, 1, stringSource);
表示1
比你未初始化的stringlen小,所以报错
请注意,此参数不会告诉函数应该复制多少个字符,而是目标应该有多大。你不告诉它只复制 1 个字符,而是告诉它它最多可以复制 1 个字符(无论如何 0 字节都需要它)。
Gives me an unhandled RangeChecks exception, whereas:
C 的数组是零索引的,这意味着对于 char stringSource[20];
,元素是从 0 到 19,当您执行 stringSource[20] = '[=11=]';
时,访问超出数组边界,这会导致未定义的行为。
Throws the exception "Buffer is too small". Whereas:
那是因为stringSource
是自动存储的,没有初始化为有效的字符串,使用它会导致未定义的行为。
而第二种情况,当你把 char stringSource[20];
放在函数之外时,数组是静态存储,它默认初始化为零值,它实际上与 char stringSource[20] = "";
相同,这就是为什么这个案例 strcpy
成功了。
我很困惑,如果这很明显,我很抱歉,但是:
int main()
{
char stringDest[20];
char stringSource[20];
strcpy_s(stringDest, stringSource);
return 0;
}
抛出异常 "Buffer is too small"。鉴于:
char stringSource[20];
int main()
{
char stringDest[20];
strcpy_s(stringDest, stringSource);
return 0;
}
工作正常。
此外,我认为保险箱的要点 strcpy_s(dest, size, source)
是您指定要复制的字节数,但是当我这样做时:
int main()
{
char stringDest[20];
char stringSource[20];
strcpy_s(stringDest, 1, stringSource);
return 0;
}
我得到一个 "Buffer is too small exception"。
我感到很困惑。为什么在 main()
之外声明变量会有所不同?为什么指定 1 个字节进行复制是错误的?
你在这里调用了未定义的行为,因为你没有初始化源字符串。
在大多数情况下,会有垃圾,第一个0
字节很可能在长度为20之后,这就是compiler/runtime抱怨的原因。
char stringSource[20] = {0};
或者
char stringSource[20] = "";
最合适的。
根据您的环境,在调试版本中,编译器可以有意地用 0xff
之类的值填充变量,以便第一个 0-byte
始终超出限制。
如果将 char stringDest[20]
放在函数外部,它将成为一个全局变量,CRT 启动时始终将其初始化为 0
。
在你的最后一个例子中,你应该看看 strcpy_s 的描述。
如果
,此变体将导致错误destsz is less or equal strnlen_s(src, destsz); in other words, truncation would occur
strcpy_s(stringDest, 1, stringSource);
表示1
比你未初始化的stringlen小,所以报错
请注意,此参数不会告诉函数应该复制多少个字符,而是目标应该有多大。你不告诉它只复制 1 个字符,而是告诉它它最多可以复制 1 个字符(无论如何 0 字节都需要它)。
Gives me an unhandled RangeChecks exception, whereas:
C 的数组是零索引的,这意味着对于 char stringSource[20];
,元素是从 0 到 19,当您执行 stringSource[20] = '[=11=]';
时,访问超出数组边界,这会导致未定义的行为。
Throws the exception "Buffer is too small". Whereas:
那是因为stringSource
是自动存储的,没有初始化为有效的字符串,使用它会导致未定义的行为。
而第二种情况,当你把 char stringSource[20];
放在函数之外时,数组是静态存储,它默认初始化为零值,它实际上与 char stringSource[20] = "";
相同,这就是为什么这个案例 strcpy
成功了。