> 文章列表 > C语言函数:内存函数memmove()以及实现与使用。

C语言函数:内存函数memmove()以及实现与使用。

C语言函数:内存函数memmove()以及实现与使用。

C语言函数内存函数memmove()以及实现与使用。

memmove():

        头文件:#include <string.h>

函数参数:

        

         可以发现memmove()函数的形参与memcpy()函数是一样的:

        C语言函数:内存函数memcpy()以及实现_srhqwe的博客-CSDN博客

        不仅形参一样,形参的意思几乎也是一样的。

作用:

        从source开始到后num个字节,拷贝到destination到后num个字节。

内存重叠:

        memcpy()函数如果遇到内存重叠,就无法得到理想的拷贝。

        而memmove()函数就恰恰解决了这一问题,可以看到memcpy留下的内存重叠问题:

        

int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };memmove(arr1+2, arr1,5*sizeof(int));return 0;
}

        memmove解决了这一问题。

        

memmove()函数的模拟实现:

        memmove函数实现的重点在于:是如何解决内存重叠问题的。

        只有解决内存重叠问题,其余的代码其实与memcpy是相近的。

内存重叠问题的解决:

         

         可以看到上图,我们将12345拷贝到34567,遇到内存重叠问题是因为,1拷贝到3,2拷贝到4,当要将3拷贝到4时,发现3以及变成了1。因此后面无法继续。

        既然src从首项1开始拿数据显然不行,那试着从末项5开始拿数据:5拷贝到7,4拷贝到6,3拷贝到5,2拷贝到4,1拷贝到3。似乎从后往前是可以的。

        似乎从后往前拷贝就可以了。

        再看:

        

        与上面作比较,src与dest交换了位置。

        此时再src从后往前是:7拷贝到5,6拷贝到4,当5要拷贝到3时,发现这里的5已经变成了7。因此又遇到了内存重叠的问题。

        那再试试从前往后:3拷贝到1,4拷贝到2,5拷贝到3,6拷贝到4,7拷贝到5.

        !此时发现,从前往后解决了内存重叠问题。

        

        一会从前往后,一会从后往前。到底怎样才是正确的呢?

        细心的会发现。当src处于dest左边的时候需要从后往前,当src处于dest右边的时候需要从前往后

        但一切的前提是,它们有内存重叠。如果没内存重叠,那么也不会遇到问题。此时无论从前往后还是从后往前都可以。

        

        我们知道,在数组内,地址的大小是由低到高变化的。下标越大地址越大。 因此:

        当dest<src时,说明dest在src左边。

        当dest>src时,说明dest在src右边。

        当dest=src时,说明dest与stc彻底重合了,

        无论dest>src还是<src,如果相差很多,导致没有内存重合。无论从前往后还是从后往前都可以。dest=src彻底重合更没得说了。都彻底重合了。那么动都不用动了。

代码实现:

       

#define _CRT_SECURE_NO_WARNINGS#include <string.h>void* my_memmove(void* dest, const void* sour, size_t num)
{if (dest < sour){for (int i = 0; i <= num; i++){*((char*)dest + i) = *((char*)sour + i);}return dest;}else if (dest > sour){for (int i = num; i >=0; i--){*((char*)dest + i) = *((char*)sour + i);}return dest;}else{return dest;}
}int main()
{int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] = { 0 };my_memmove(arr1+2, arr1,5*sizeof(int));return 0;
}

        

        代码和memcpy很像,不同的就是多了条件判断,以及从后往前拷贝。