字符串复制说缓冲区太小,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 成功了。