Simulate implementation of memcpy and memmove

Table of Contents

Foreword:

memcpy:

Introduction:?Editor

Simulate implementation of memcpy:

memmove:

introduce:

Simulate implementation of memmove:

Summarize:


Foreword:

In the previous blog, we discussed string functions such as strcpy and strcmp and their simulation implementation.

Today, we focus on the two memory functions memcpy and memmove, and simulate their implementation.

First we need to know the difference between memory functions and string functions.

String functions like strcpy and ctrcmp all use strings, but are not applicable to integers or floating point types, so we introduce memory functions here.

Memory functions like memcpy and memmove are used for various data in memory. They can not only operate on strings but also on integer arrays or character arrays. Next we introduce these two functions.

memcpy:

Introduction:

For memcpy its code is as follows:

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

destination—-is the area to which the source needs to be copied.

source – copies the source to the destination.

num–unit, indicating how many bytes to copy to destination.

The specific operations are as follows:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
int destination[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int source[] = { 9, 10 };
memcpy(destination, source, 8);
\t
int sz = sizeof(destination) / sizeof(destination[0]);
for (int i = 0; i < sz; i + + )
{
printf("%d ", destination[i]);
}
return 0;
}

We expect the output9, 10, 3, 4, 5, 6, 7, 8

The actual output is consistent with the expected result.

Next let’s talk about how to simulate and implement memcpy

Simulation and implementation of memcpy:

In the introduction just now, we know that the expression of memcpy is

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

We need to know the return types of each of their entries, which are basically void*, so implementing them is exactly the same as implementing qsort.

code show as below:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memcpy(void* destination, const void* source, size_t num)
{
assert(destination & amp; & amp; source);
void* ret = destination;
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
//Note that (char*)destionation + + is not allowed, because forced type conversion is temporary and will disappear after use. In this way, void* is added to + +.
//And void* cannot perform + + operations.
}
return ret;
}

int main()
{
int destination[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int source[] = { 9, 10 };
//memcpy(destination, source, 8);
my_memcpy(destination, source, 8);

int sz = sizeof(destination) / sizeof(destination[0]);

for (int i = 0; i < sz; i + + )
{
printf("%d ", destination[i]);
}
return 0;
}

The operation method of the following code is similar to the algorithm we used to implement the qsort function before. For details, please refer to the previous qsort blog.

 *(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;

Independent implementation of qsort function_Wu Shuang@’s blog-CSDN blog

memmove:

Introduction:

We will find that the return types of each parameter of this function are very similar to memcpy. In fact, yes, we can understand memmove as a more complete memcpy. We do not need to understand them deeper at this stage.

When to use memmove?

Let’s first talk about the shortcomings of my_memcpy:

If we need to overwrite the copies of 1,2,3,4,5 in destination to 3,4,5,6,7

The expected result should be:

1,2,3,4,5,8

But if we use my_memcpy, the following results will appear:

void* my_memcpy(void* destination, const void* source, size_t num)
{
assert(destination & amp; & amp; source);
void* ret = destination;
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
//Note that (char*)destionation + + is not allowed, because forced type conversion is temporary and will disappear after use. In this way, void* is added to + +.
//And void* cannot perform + + operations.
}
return ret;
}

int main()
{
int destination[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
//int source[] = { 9, 10 };
//memcpy(destination, source, 8);
my_memcpy(destination + 2, destination, 20);

int sz = sizeof(destination) / sizeof(destination[0]);

for (int i = 0; i < sz; i + + )
{
printf("%d ", destination[i]);
}
return 0;
}

The final output is different from what we expected.

As shown in the picture, the next step is to implement the operation.

When we finish copying 1 and 2, when we are about to copy 3, we will find that we cannot find 3, the position of 3 becomes 1, and the position of 4 also becomes 2.

That’s why there are repeated 1, 2, 1, 2.

Therefore, in the face of this situation, we can use memmove to implement it, or sort in reverse order. As shown in the picture:

memmove(destination + 2, destination, 20);

Then output the result and you will get the data consistent with the expectation:

This is the difference between memmove and memcpy.

But if you try to use memcpy to copy, you will find that the expected results are the same as memmove.

That’s because the VS compiler optimizes memcpy.

Next, let’s talk about the simulation implementation of memmove

Simulate implementation of memmove:

The specific code is as follows:

#include<assert.h>
void* my_memmove(char* destination, const void* source, size_t num)
{
assert(destination & amp; & amp; source);
void* ret = destination;
if (destination < source)
{
//Go and copy
for (int i = 0; i < num; i + + )
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
else
{
//Copy from back to front
while (num--)
{
*((char*)destination + num) = *((char*)source + num);
}
}
\t
return ret;
}

int main()
{
int destination[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
//int source[] = { 9, 10 };
//memcpy(destination, source, 8);
memmove(destination + 2, destination, 20);

int sz = sizeof(destination) / sizeof(destination[0]);

for (int i = 0; i < sz; i + + )
{
printf("%d ", destination[i]);
}
return 0;
}

Let’s focus on the pseudocode:

void* my_memmove(char* destination, const void* source, size_t num)
{
assert(destination & amp; & amp; source);
void* ret = destination;
if (destination < source)
{
//Go and copy
for (int i = 0; i < num; i + + )
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
else
{
//Copy from back to front
while (num--)
{
*((char*)destination + num) = *((char*)source + num);
}
}
\t
return ret;
}

This part is to determine the relationship between destination and source. If our destination is smaller than source at this time, then we cannot copy from forward, but should choose to copy from front to back. Otherwise, the cause of the error is the same as mentioned above and it will be occupied. Lose.

Implementing copy is also similar to the qsort function, so I won’t go into details here.

The specific method is to convert destination and source from void* to char*.

The next step is that when the destination is larger than the source, the selected one is copied from back to front.

It is currently as shown in the figure:

When I want to access the last element pointed to by source and destination, I can choose to add sum

The specific explanation is as follows:

If we add 4, we skip an integer, and the pointer will point to:

It will point to the first byte of the next element.

Therefore, we need + num and then -1, but when we make a judgment in the while statement, we have already implemented num post—, so there is no need to perform -1 operation.

The result of running this is:

The above is the implementation process of my_memove.

Summary:

In this article, we mainly explain the memory functions of memcpy and memmove, and simulate and implement these two functions.

We learned here that we can come down and try to write it ourselves.

This way we will become more familiar with it.

remember

“Actions speak louder than words”

Action speak louder than words!

If you want to see the source code first, you can visit my Gitee:

Test_memcpy_memmove_CSDN/Test_memcpy_memmove_CSDN/test.c · Wushuang/test_c_with_X1 – Gitee.com