memmove函数和memcpy函数的模拟实现

简介: memmove函数和memcpy函数的模拟实现

首先我们来了解memmove函数和memcpy函数的使用

memmove函数

他的函数所需参数如下

1.函数memcpy从source的位置开始向后复制num个字节的数据destination 指向的内存位置。

2.这个函数在遇到 ‘\0’ 的时候并不会停下来。

3.如果source和destination有任何的重叠,复制的结果都是未定义的

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

我们要注意,这里的num是以字节为单位的,而不是元素个数,并且由于这里我们不知道memmove所移动的内容是什么数据类型,所以移动的目的和源头都用void来定义,由于memmove函数还需有返回目的的起始地址,所以函数类型定义为void**。

下面我们就可以对memmove函数进行模拟实现

我们定义此模拟实现函数为my_memmove

我们定义数组

arr[]={1,2,3,4,5,6,7}

我们想要将数组中数字3,4,5放入1,2,3的位置中,也就是说src中的内容从前向后移动到det中,反之,如果采用从后向前将不会达到我们想要的下图的数组,移动后的数组内容如下图所示

我们将数组移动的内容进行分析,此时det在src的前面,我们可以先将数字3放入arr[0],然后一次放入4,5

下面来看另外一种情况,就是如果det在src的后面呢,该如何移动呢

这个时候我们就会发现从前向后的方法并不适用与这种情况了,我们可以采用从后向前的方式,若依旧采用从前向后的方式的话,会是这种效果

这个时候我们就可以开始构思函数了

由于函数最终需要返回det的起始地址,所以我们定义一个void* ret=det放入函数中,并且采用断言保证不为空指针

void my_memmove(void* det, void* src, size_t size)
{ 
        assert(det && src);
        void* ret = det;
}

接下来分析当det在src前面是的移动方式

由于不知道数据的类型,并且size的单位是字节,但是当数据的类型是int的时候,循环进行是该如何移动呢,我们就可以将det的指针类型强制转化为char*指针,就可以进行字节“++”操作了

if (det < src)//从前往后移动
  {
    int i = 0;
    for (i = 0; i < size; i++)
    {
      *(char*)det = *(char*)src;//强制类型转换
      arr1 = (char*)det + 1;
      arr2 = (char*)src + 1;
    }

反之,我们就写出det在src之后的部分

while (size--)
    {
      *((char*)det + size) = *((char*)src + size);
    }

到这里,memmove的模拟实现就完成了,我们还要记得返回ret,也就是det的起始地址

完整函数代码如下

void my_memmove(void* det, void* src, size_t size)
{
  assert(det && src);
  void* ret = det;
  if (det < src)//从前往后移动
  {
    int i = 0;
    for (i = 0; i < size; i++)
    {
      *(char*)det = *(char*)src;
      arr1 = (char*)det + 1;
      arr2 = (char*)src + 1;
    }
  } 
  else
  {
    while (size--)
    {
      *((char*)det + size) = *((char*)src + size);
    }
  }
  return ret;
}

memcpy函数

相对于memmove函数,memcpy的功能就没有怎么完整了,memmove和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的,所以,如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。但是,有一些编译器的memcpy也可以处理重叠的的情况,就比如vs。

memcpy的模拟实现和memmove的差别不大

代码如下

void * memcpy ( void * det, const void * src, size_t size)
{
 void * ret = det;
assert(arr1 && arr2);
 while (size--) {
 *(char *)dst = *(char *)src;
 dst = (char *)dst + 1;
 src = (char *)src + 1;
 }
 return(ret);
}

大家可以发现,memcpy函数的模拟实现就是memmove函数模拟实现的一部分,就是只采用了从前向后的方式进行内存更改,所以这里我就不做过多的解释了,大家自行理解。

好了,今天的分享就到这里了!

相关文章
|
7月前
|
安全 C++
内存函数 memcpy 和 memmove 的讲解和模拟实现
内存函数 memcpy 和 memmove 的讲解和模拟实现
29 0
|
8月前
|
C语言
【C语言】memcpy函数和memmove函数使用和模拟实现
【C语言】memcpy函数和memmove函数使用和模拟实现
46 0
|
2月前
|
编译器 C++
C++中memcpy函数的实现
C++中memcpy函数的实现
|
4月前
带你全面了解四大内存操作函数memset(),memcpy(),memmove(),memcmp()(附模拟实现)
带你全面了解四大内存操作函数memset(),memcpy(),memmove(),memcmp()(附模拟实现)
|
4月前
|
算法 编译器 C语言
memcpy内存拷贝函数
memcpy内存拷贝函数
37 0
|
4月前
memmove内存拷贝函数
memmove内存拷贝函数
17 0
|
9月前
|
C语言
模拟实现库函数,strtsr,memmove.
<1>主页:C语言的前男友 <2>知识讲解:模拟实现 库函数 strstr,memmove <3>创作者:C语言的前男友 <4>开发环境:Visual Studio 2022 <5>前言:学习了strstr,memnove等库里面的内存相关的函数,功能非常的强大。今天我们来模拟实现一下。
|
7月前
|
存储 安全
memcpy和memmove函数的介绍和模拟实现
memcpy和memmove函数的介绍和模拟实现
【memcpy和memmove函数的详解】
我们知道,strcpy函数是拷贝字符串的,但是它并不能拷贝例如整型,结构体之类的东西,strcpy有一定的局限性,memcpy函数可以说涵盖了所有类型数据的拷贝。