Play with the memory modification function - [C language]

In the last blog, we learned string functions, and we can perform a series of operations on some strings. Next we will learn some memory modification functions (#inlcude<string.h>), let us walk into the mempy, memmove, and memcmp functions together.


Table of contents

mempcy functionEdit

memmove function

memcmp function


mempcy function

Through the function prototype, we can see that the return value and some pointer parameter types are void* types, which means that this function is not limited to strings, but can be implemented for integer arrays, structure arrays, etc., size_t num parameters The unit is byte, because the type of the previous pointer is void*, we do not know the element type of the incoming array, so the unit of the third parameter is byte, and many data types can be copied.

The memcpy function is a function for copying a memory block. The function memcpy copies num bytes of data backwards from the source position to the destination memory position.

1. Parameters: The destianation pointer is to receive the address of the first element of an array of any type, which is used as the target.

The source pointer also receives the same type of pointer variable, which is used to copy the content.

size_t num is the number of bytes to copy.

2. Return value: return the pointer of the target.

3. The function does not stop at '\0' , the function does not check the source for any terminating null characters - it always copies exactly the number of bytes .

4. If there is any overlap between source and destination, the result of the copy is undefined.

 Next reference to the memcpy function:

int main(void)
{
	int arr1[] = {1,2,3,4,5,6,7,8,9,10};
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 40);
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

Copy the 40 bytes of memory content in arr1 to arr2. There are 20 zeros in arr2, but only 10 elements in arr1 are copied, so the first 10 elements in arr2 will be overwritten by the content in arr1, the result is as follows: Next, we simulate the implementation of the memcpy function  :

模拟实现
void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(src && dest);
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

int main(void)
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_mempy(arr2, arr1, 40);
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

We create a my_memcpy function, modeled after the memcpy function prototype to create a custom function prototype. Because the return value is the first element pointer of the target array, we first create a void* pointer to mark the target array. Then use the while loop to assign values ​​byte by byte. Because the memcoy function can target any kind of array, we should cast all void* type pointers to pointers of the smallest unit char* type, so that it can be compatible with all kinds of arrays. When the assignment is completed, add 1 to the pointer (for pointers of void* type, we cannot perform ++ operations on it, so we can only write it in the form of dest = (char*)dest + 1;). When num-- reaches 0, it proves that all assignments have been completed, just jump out of the loop and return to the original pointer.

Here are the results of our run:

Same result as we got with the memcpy function originally.

Next we have another question, can we use the memcpy function to copy the contents of an array to ourselves? To put it more simply: there is an integer array int arr1[] = {1,2,3,4,5,6,7,8,9,10}; 1, 2, 3, 4, 5 in arr1 Put it on the position of 3, 4, 5, 6, 7?

int main(void)
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	
	memcpy(arr1 + 2,  arr1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

We think of the final content in arr1: 1,2,1,2,3,4,5,8,9,10 but what is the result?

 So why is this so?

So what should we do to complete the content just now? This is done using the memmove function! !


memmove function

 The memmove function is a function that will move a block of memory, copying the value of the number of bytes from the location pointed to by the source to the memory block pointed to by the destination . Copying is as if using an intermediate buffer, allowing the destination and source to overlap.

1. The return value and parameters are the same as the mempy function, we can refer to the above for understanding.

2. The underlying type of the object pointed to by the source and destination pointers is irrelevant to this function; the result is a binary copy of the data.
The function does not check the source for any terminating null characters - it always copies exactly the number of bytes .
To avoid overflow, the size of the arrays pointed to by the destination and source arguments should be at least the number of bytes .

3. The difference with memcpy is that the source memory block and target memory block processed by the memmove function can overlap. If the source space and the target space overlap, you have to use the memmove function to deal with it.

 Next let's use the memmove function to complete the above problem:

int main(void)
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1 + 2, arr1, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

 Completed the question just now very smoothly.

Now let's simulate the implementation of the memmove function:

void* my_memmove(void* dest,const void* src, size_t num)
{
	void* ret = dest;
	if (dest < src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
		return ret;
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
}


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

 Create a my_memmove function, and follow the memmove prototype to complete the parameters of the custom function. But how should we complete the function body?

Just using the most basic copy from front to back, you can't get the desired result. If you copy from back to front, you can get the desired array. In the case of writing, we need to copy from front to back, so I will summarize for you:

So we score the situation to complete the custom function body, when the dest pointer <src pointer, the content inside is the same as my_memcpy content. When the dest pointer>src pointer, we continue to use the while loop and copy from back to front to complete. The pointer can be accessed from the back to the front by adding the number of nun bytes before each dereference, while the judgment condition is num--, and the pointer can also be moved when judging whether it is over, killing two birds with one stone. Finally, return the address of the first element of the target array. The only difference from the my_memcpy function must be discussed separately.

The result of the operation is as follows:

 This function simulation is complete!

For the above two functions, there will be a question here, whether the memmove function can do what the memcpy function can do. That's for sure. So the role of the memmove function must be higher than the mempy function! ! !


memcmp function

 The memcmp function compares two memory blocks, which is somewhat similar to the strcmp function. It compares whether the two arrays are the same, and the return value is the same. But the difference is that memcmp can compare more types. This function will not stop comparing after finding a null character, but strcmp will stop.

PTR1

A pointer to a block of memory.

PTR2

A pointer to a block of memory.

number

The number of bytes to compare.

It does a byte-by-byte comparison by comparing data stored in memory.

 Here is an example using the memcmp function:

int main(void)
{
	int arr1[10] = { 1,2,1,4,5,6 };
	int arr2[10] = { 1,2,257 };
	int ret = memcmp(arr1, arr2, 9);
	printf("%d\n", ret);

	return 0;
}

Compare whether the first 9 bytes in arr1 and arr2 are the same?

 The storage content of the first 10 bytes in arr1

The first 10 bytes in arr2 store content 

Because we are comparing the contents of the first 9 bytes, they are all the same, and the output value should be 0;  if we compare the first 10 bytes, the output should be -1; 

The above is all my understanding of the memory modification function, I hope you guys can give me valuable advice in the comment area! 

Guess you like

Origin blog.csdn.net/m0_74755811/article/details/131739369