Analysis and implementation of memory function memcpy memmove

Posted by kparish on Sun, 20 Feb 2022 05:34:42 +0100

1. Introduction and use of several common memory functions

In the string library functions, strcpy and other functions can easily modify the string, but if they are replaced with int, double and other types of data, the str family seems powerless. Therefore, the mem family (memory function) was born and can easily solve such problems

First, let's take a look at the function prototypes and introductions officially given by memcpy and memmove

Recommended websites:

en.cppreferrence.com

cplusplus.com

The function of memcpy and memmove is to copy the first count bytes at the src pointer to dest

Special note: size here_ T count is the number of bytes

They have three parameters: target pointer dest source address src bytes count

Here, the developer sets the two key pointers and the return type of memcpy/memmove to void*

The reason is to adapt, because the developer cannot know the type that the user adapts when calling the function, so it is set to changeable - void *

For example, try to use these two functions (take memcpy as an example, and the use of memmove is the same)

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[10] = {1,2,3,4,5,6,7,8,9};
	int arr2[10] = { 0 };
	memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

You want to copy the first 20 bytes of elements in arr1 to arr2 and print them. This is the function of memory function memcpy

The effect is as follows →:

2.memcpy Simulation Implementation

The finished products are as follows:

//Simulation Implementation of memcpy
void* my_memmcpy(void* dest, const void* src, size_t n)
{
	void* ret = dest;
    assert(dest&&src);
	while (n--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

Because we will not modify the source pointer when executing the memcpy function, we add const modification here;

char * one byte is the unit, and the forced type conversion is consistent with the number of bytes we want to copy;

However, forced type conversion is temporary. When we operate dest and src, we should avoid dest + +, src + +. We also need to carry out forced type conversion, copy one byte dest and src, and go back one byte;

Here, assert is used to ensure that dest and src pointers are non null pointers;

3. The difference between memcpy and memmove

Let's look at this code first

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10};
	my_memcpy(arr + 2, arr, 5 * sizeof(arr[0]));
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

At this time, we use our own design_ The expected result of the memcpy function is

1 2 1 2 3 4 5 8 9 10

But we will be surprised to find that the operation results are different from what we thought

Why?

In this case, the memory is overwritten. The 3 4 5 we originally want to copy is overwritten by the 1 2 1 that we copied. As a result, 1 2 1 is copied when we want to copy 3 4 5 later;

Special note special note: if you use vs compiler like bloggers, memcpy can solve the problem of memory overlap here. We can use memcpy to get the expected effect in the figure below (memcpy may not support overlapping copies under some compilers);

However, the C language library only requires memcpy to deal with memory non overlapping and memmove to deal with memory overlapping;

At this time, you need to use the memmove function. When copying, memmove allows memory overlap;

This is the copy effect we want

In fact, when dealing with such problems, mindless use memmove to finish it;

 

4.memmove Simulation Implementation

The finished products are as follows:

//Simulation Implementation of memmove
void my_memmove(void* dest, const void* src, size_t n)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)
	{
		while (n--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src =(char*)src + 1;
		}
	}
	else
	{
		while (n--)
		{
			*((char*)dest + n) = *((char*)src + n);
		}
	}
	return ret;
}

The details are the same as those of memcpy implementation;

When implementing the overlap problem in 3, we can copy backwards

Dest > SRC

However, when dest < SRC, the memory overlap will also appear in the reverse copy

So here we are trying to copy, a classification to solve the problem;  

5. Summary

memcpy is the product of the birth of C language in the history of development, which can not be erased, but it is not meaningless;

When we need to use memory function copy, we can use memmove;

If there are mistakes, correct them more; Grow up together, come on!

Topics: C