451-memcpy、memmove、memset的实现

1、memcpy和memmove的作用 & 区别

1.1、memcpy

memcpymemmove都是C语言中的库函数,包含于头文件string.h中。

void * memcpy ( void * destination, const void * source, size_t num );

memcpy的作用:

  • 把source指针指向的位置处的num个字节的内存块拷贝到destination指针指向的位置处。
  • 不允许源指针和目的指针指向的内存区域有重叠,会不安全

1.2、memmove

void * memmove ( void * destination, const void * source, size_t num );

作用:

  • memmove也可以把source指针指向的位置处的num个字节的内存块拷贝到destination指针指向的位置处;
  • memcpy不一样的是,memmove拷贝的时候会以一段缓冲区作为媒介,所以允许源指针和目的指针指向的内存区域有重叠

2、内存重叠

下面举个例子说明一下内存重叠是什么意思:

在这里插入图片描述

  • 当我们想把2 3 4 5拷贝到4 5 6 7处去的时候,这两块区域就发生了重叠;
  • 如果使用memcpy的话,我们会发现2和3已经替代了4和5,我们没有办法再把4和5拷到6和7处去了,结果就变成了1 2 3 2 3 2 3 8,而这不是我们想要的结果;
  • 但是使用memmove的话,我们还是可以得到1 2 3 2 3 4 5 8。

上面那个例子如果是从后往前拷的话就不会发生那样的问题!
再进一步总结:

  • 只要目的地址在源地址之前就不会出现问题,可以从前往后拷;
  • 若目的地址在源地址之后可能会有问题,需要从后往前拷。

3、代码实现

3.1、memcpy

//模拟实现memcpy
void* Memcpy(void* des, const void* src, size_t num)
{
    if (des == NULL || src == NULL)
        return NULL;

    char* desStr = (char*)des;
    const char* srcStr = (const char*)src;
    while (num)
    {
        *desStr++ = *srcStr++;
        --num;
    }

    return des;
}

3.2、memmove

//模拟实现memmove
void* Memmove(void* des, const void* src, size_t num)
{
    if (des == NULL || src == NULL)
        return NULL;

    char* desStr = (char*)des;
    const char* srcStr = (const char*)src;
    if (des < src)   //目的地址在源地址之前,从前往后拷
    {
        while (num--)
        {
            *desStr++ = *srcStr++;
        }
    }
    else   //目的地址在源地址之后,从后往前拷
    {
        while (num--)
        {
            *(desStr + num) = *(srcStr + num);
        }
    }
    return des;
}

4、测试

void test()
{
    int i = 0;
    int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    Memcpy(arr1, arr1+3, 4*sizeof(int));
    Memmove(arr2 + 3, arr2 + 1, 4 * sizeof(int));
    for (i = 0; i < 8; i++)
    {
        printf("%d ", arr1[i]);
    }
    printf("\n");
    for (i = 0; i < 8; i++)
    {
        printf("%d ", arr2[i]);
    }
    printf("\n");
}

3、memset

void *memset(void *str, int c, size_t n)

作用:

  • 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

参数:

  • str – 指向要填充的内存块。
  • c – 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
  • n – 要被设置为该值的字符数。

测试:

#include <stdio.h>
#include <string.h>
 
int main ()
{
   char str[50];
 
   strcpy(str,"This is string.h library function");
   puts(str);
 
   memset(str,'$',7);
   puts(str);
   
   return(0);
}

结果:

This is string.h library function
$$$$$$$ string.h library function

自己实现:


void *my_memset(void *dest, int set, unsigned len)
{
	if (dest == NULL || len < 0)
	{
		return NULL;
	}
	char *pdest = (char *)dest;
	while (len-->0)
	{
		*pdest++ = set;
	}
	return dest;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liufeng2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值