Upgraded version of memcpy————>memmove function

Foreword:

Continuing from the previous chapter, let’s continue to explain string functions and memory functions. This issue is about the memmove function. This function is much easier to use than the memcpy function in the previous section! ! ! Without further ado, let’s talk!


What is the memmove function?

By consulting MSDN (C language's all-purpose guide!), we can see that the return value type of memmove and the parameter type are exactly the same as the memcpy function! The header file is string.h

From the literal meaning, we can know that memmove means memory move, which translates to memory move. It is obvious that memmove moves count bytes of the source memory block to the target memory block.

Notice:

The src parameter is modified with const, which means that the content pointed to by src cannot be changed through src.

Then the movement here is not that after the source is taken to the target, the source is gone. Instead copies the contents of the source memory block and then moves it to the target memory block.

See example:

The array arr1 of this program is the target memory block, and the array arr2 is the source memory block. Obviously, arr1 has been changed, but arr2 is still the original array.


How to use memmove function?

The usage of memove is exactly the same as the usage of memcpy function, so I won’t go into details here. If you don’t understand, go to the previous section.

What is the difference between memmove function and memcpy function?

Let’s see an example:

In this program, we use our own defined memcpy function to copy the 20 bytes of the arr1 array memory block

Copy to the memory block pointed to by arr1+2. The ideal print result should be 1 2 1 2 3 4 5 8 9 10

But the actual result is 1 2 1 2 1 2 1 8 9 10.

Cause Analysis:

The reason why the memcpy function is not used here is that after experiments, in the VS compiler memcpy will be copied normally into

1 2 1 2 3 4 5 8 9 10 (but this is not necessarily true for other compilers), so use the custom my_memcpy function as an example. Then in order to solve the problem of copying under overlapping memory blocks, the memmove function comes in handy.

Next, let's see what happens when we use the memmove function to copy in the same scenario?

We found that using memmove can copy normally. So why can the memmove function copy normally?

This depends on an optimization of memmove relative to memcpy.

Because there are always special cases where the source memory block and the target memory block overlap. In these memory overlap cases, there are Sometimes you can copy normally by copying from front to back, sometimes you can copy normally by copying from back to front, and sometimes you can copy normally.

Then I will take you to analyze when and what order to copy:

It is worth mentioning that:

When memory overlaps, sometimes the content pointed to by src is changed. This is not a definition error. But when the memory blocks pointed to by src and dest overlap, that part of the content is changed through dest, not through src. So it's still no problem.


Then after learning to distinguish the copy order, we can easily customize the my_memmove function!

Custom memmove function

The definition of copying from front to back is the same as the memcpy function. Copying from back to front is mainly num-- to control the number of copies.

void* my_memmove(void* dest, const void* src, size_t num)
{
    assert(dest && src);
    void* ret = dest;
    if (dest < src)//从前向后拷贝
    {
        while (num--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    else//从后向前拷贝
    {
        while (num--)
        {
            //*(char*)dest = *(char*)src;
            //dest = (char*)dest - 1;
            //src = (char*)src - 1;
            *((char*)dest + num) = *((char*)src + num);//这样更简洁 
        }
    }
    return ret;
}
int main()
{
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    int arr2[8] = { 0 };
    memmove(arr1 + 2, arr1, 20);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ", arr1[i]);//1 2 1 2 3 4 5 8 9 10 
    }
    return 0;
}

The custom function code is obtained by yourself.


Conclusion:

At this point, this chapter’s content about the memmove function ends. In the future, you can use memmove if you encounter problems that memcpy cannot solve. If you like it, please give it a like! Looking forward to our next encounter!

Finally, it’s the old saying:The road is long and long, but I will search high and low! ! !

Guess you like

Origin blog.csdn.net/qq_74292674/article/details/129617842