memcpy_s
是一个安全版本的 memcpy
函数,它在标准 C 库中并不直接提供,但它是某些安全编码标准(如 Microsoft 的安全开发生命周期 SDL)推荐的函数,旨在减少缓冲区溢出的风险。这个函数的行为与 memcpy
类似,但它要求程序员明确指定目标缓冲区的大小,从而避免了由于缓冲区大小错误而导致的溢出。
1 函数原型
在不同的实现中,memcpy_s
的具体函数原型可能略有不同,但一个典型的原型可能如下所示:
errno_t memcpy_s(void *dest, size_t destSize, const void *src, size_t count);
dest
是指向目标缓冲区的指针。destSize
是目标缓冲区的大小(以字节为单位)。src
是指向源数据的指针。count
是要复制的字节数。
2 返回数
- 如果函数成功执行,则返回
0
。 - 如果发生错误(如目标缓冲区太小,无法容纳要复制的字节数),则返回非零值,并可能设置
errno
以指示具体的错误原因。
3 使用示例
#include <string.h>
#include <stdio.h>
int main() {
char dest[10];
const char src[] = "Hello, world!";
// 使用 memcpy_s 复制字符串,但限制复制的长度以避免溢出
if (memcpy_s(dest, sizeof(dest), src, sizeof(src) - 1) == 0) {
// 注意:由于我们限制了复制的字节数,所以可能不会复制整个 src 字符串
// 在这个例子中,我们实际上应该根据 dest 的大小来限制复制的字节数
dest[sizeof(dest) - 1] = '\0'; // 确保字符串以 null 结尾
printf("Copied: %s\n", dest);
} else {
printf("memcpy_s failed.\n");
}
// 更安全的做法
if (memcpy_s(dest, sizeof(dest), src, sizeof(dest) - 1) == 0) {
dest[sizeof(dest) - 1] = '\0';
printf("Safely copied: %s\n", dest);
} else {
printf("Safe memcpy_s failed.\n");
}
return 0;
}
注意,在使用 memcpy_s
时,你需要确保 count
参数不会超出 destSize
,以避免溢出。在这个例子中,我们第一次尝试复制整个 src
字符串,这可能会导致缓冲区溢出(如果 src
的长度大于 dest
的大小)。在第二次尝试中,我们限制了复制的字节数,从而避免了这个问题。
运行结果如上图。如果对您有帮助的话,请点个赞。