【学习笔记】memcpy_s 函数与坑
所以实际填写的值应该是 destSize 和 count 都为 10 * 4(即 10 个元素,每个元素占用 4 个字节)。函数赋值到 dest 中,最开始我以为 destSize 和 count 表示的是元素个数,于是填写的都是 10,如下。这里有一个坑,那就是关于 destSize 和 count 的值,它们都是指的字节数(最开始我以为是元素个数)。是在内存级别上直接进行拷贝操作,但注意它一次
![](https://csdnimg.cn/release/devpress/public/img/ic-book.4f347164.png)
函数原型
errno_t memcpy_s(void *dest, size_t destSize, const void *src, size_t count);
函数描述
memcpy_s
函数,从 src 中复制 count 个字节到 dest 中。它是 memcpy
的安全版本,因为参数中限制了目标内存区域的大小。
是在内存级别上直接进行拷贝操作,但注意它一次拷贝的数量为一个字节,而不是一个位(比特)。
参数描述
- dest:目标数组,或者说目标内存区域
- destSize:目标内存区域的大小,其单位是字节
- src:源数组,或者说源内存区域
- count:要复制的源内存区域元素的个数,其单位是字节
返回值
如果成功则返回零(来自 MSDN)
坑
这里有一个坑,那就是关于 destSize 和 count 的值,它们都是指的字节数(最开始我以为是元素个数)。
举一个例子,比如我有如下数组:
long src[10] = { 1,2,3,4,5,6,7,8,9,10 };
long dest[10] = { 0 };
现在我将 src 中的元素通过 memcpy_s
函数赋值到 dest 中,最开始我以为 destSize 和 count 表示的是元素个数,于是填写的都是 10,如下。
void Malloc_m_memcopy()
{
long src[10] = { 1,2,3,4,5,6,7,8,9,10 };
long dest[10] = { 0 };
memcpy_s(dest, 10, src, 10);
for (int i = 0; i < 10; i++)
{
printf("%d ", dest[i]); // 1 2 3 0 0 0 0 0 0 0
}
}
显然,printf 打印的数据不正常。因为实际上,destSize 和 count 都是以字节数为单位,而非个数。
所以我们看上面,long 在我的环境中(windows10 64位,vs2015 下)其大小为 4 个字节。所以实际填写的值应该是 destSize 和 count 都为 10 * 4(即 10 个元素,每个元素占用 4 个字节)。
下面是正确的代码:
void Malloc_m_memcopy()
{
long src[10] = { 1,2,3,4,5,6,7,8,9,10 };
long dest[10] = { 0 };
memcpy_s(dest, 10 * 4, src, 10 * 4);
for (int i = 0; i < 10; i++)
{
printf("%d ", dest[i]); // 1 2 3 4 5 6 7 8 9 10
}
}
可以看到正常输出了。
或者你也可以用 sizeof
函数来计算 src 和 dest 占用的元素的字节数,sizeof
用来计算对象或类型在当前系统下占用内存的字节数
【注】sizeof
返回的是变量在当前编译器下的字节数
void Malloc_m_memcopy()
{
long src[10] = { 1,2,3,4,5,6,7,8,9,10 };
long *dest = (long *)malloc(sizeof(long) * 10 );
memcpy_s(dest, sizeof(long) * 10, src, sizeof(src));
for (int i = 0; i < 10; i++)
{
printf("%d ", dest[i]); // 1 2 3 4 5 6 7 8 9 10
}
}
参考
- memcpy_s:msdn
- memcpy_s:cppreference
- memcpy_s in C:比参考 1,2 总结的好
- What is size_t in C?:StackOverflow
- size_t data type in C
- Why is rsize_t defined?:StackOverflow
拓展
- Copying overlapping memory:memcpy 存在的内存重叠问题
更多推荐
所有评论(0)