C language from entry to practical use - understanding and simulation implementation of commonly used memory functions


Preface

Memory functions refer to functions that control computer memory operations


1. Memcpy usage and simulation implementation

void * memcpy ( void * destination, const void * source, size_t num ); 
  • Functionmemcpy copies bytes of data backward starting from the position of source to The memory location pointed to by . num destination
  • This function will not stop when encountering '\0' .
  • If there is any overlap between source and destination , the result of the copy is undefined.
    Insert image description here
    Insert image description here
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = {
    
     0 };
	memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", arr2[i]);
	}
	return 0;
}

Insert image description here

For overlapping memory, leave it to memmove for processing.

memmove can also achieve non-overlapping and is more powerful than memcpy

Simulation implementation of memcpy function:

assertAssertion function, used to assert pointers,count used to count, copy bytes according to the number of input digits

void * memcpy ( void * dst, const void * src, size_t count)
{
    
    
	void * ret = dst;
	assert(dst);
	assert(src);
/*
* copy from lower addresses to higher addresses
*/
	while (count--) {
    
    
	*(char *)dst = *(char *)src;
	dst = (char *)dst + 1;
	src = (char *)src + 1;
	}
	return(ret);
}

2. Memmove usage and simulation implementation

void * memmove ( void * destination, const void * source, size_t num ); 
  • The difference between and memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
  • If the source space and target space overlap, you have to use the memmove function.
    Insert image description here
    Insert image description here
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", arr1[i]);
	}
	return 0;
}

Output result:

1 2 1 2 3 4 5 8 9 10 

Insert image description here

memmove Simulation implementation of :
Regarding the memmove function, it needs to be case-specific.
Insert image description here
As shown in the figure above, it is necessary to There are two situations. The reason why this happens is because when the string copies itself, its original data will be overwritten, resulting in such an error

void * memmove ( void * dst, const void * src, size_t count)
{
    
    
	void * ret = dst;
	if (dst <= src || (char *)dst >= ((char *)src + count)) {
    
    
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
	while (count--) {
    
    
	*(char *)dst = *(char *)src;
	dst = (char *)dst + 1;
	src = (char *)src + 1;
		}
	}
	else {
    
    
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
	dst = (char *)dst + count - 1;
	src = (char *)src + count - 1;
	while (count--) {
    
    
	*(char *)dst = *(char *)src;
	dst = (char *)dst - 1;
	src = (char *)src - 1;
		}
	}
	return(ret);
}

3. Use of memset function

void * memset ( void * ptr, int value, size_t num ); 

memset It is used to set the memory and set the value in the memory to the desired content in bytes.
Insert image description here
Insert image description here

#include <stdio.h>
#include <string.h>
int main ()
{
    
    
	char str[] = "hello world";
	memset (str,'x',6);
	printf(str);
	return 0;
}

Output result:
Insert image description here

xxxxxxworld 

Note:memset is set in bytes. Wrong use may lead to uncontrollable situations. The following is aboutAn incorrect use of this is an array of type, the following will appear In the case of is set in bytes. If it is used to set an array of type memset, because memsetint
char

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char str[] = "hello world";
	memset(str,'1', 6);
	printf(str);
	return 0;
}

Insert image description here
This is an array of type int

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	int str[] = {
    
    1,2,3,4,5,6,7,8,9};
	memset(str,'1', 6);
	for (int i = 0; i < (sizeof(str) / sizeof(str[0])); i++)
	{
    
    
		printf("%d\n", str[i]);
	}
	return 0;
}

Insert image description here
When we call the memory, memset sets each bit to '1', so we usually use memset to set data of type char, because data of type char is 1 bytes, and The int type is 4 bytes, which will cause an error
Insert image description here

4. Use of memcmp function

int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 
  • The comparison starts from the position pointed by the ptr1 and ptr2 pointers, and goes backward num bytes
  • The return value is as follows:
    Insert image description here
#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char buffer1[] = "DWgaOtP12df0";
	char buffer2[] = "DWGAOTP12DF0";
	int n;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));
	if (n > 0)
		printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
	else if (n < 0)
		printf("'%s' is less than '%s'.\n", buffer1, buffer2);
	else
		printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
	return 0;
}

Insert image description here

int my_memcmp (const char * str1, const char * str2,siez_t num)
{
    
    
	int ret = 0 ,count = 0;
	assert(str1 != NULL);
	assert(str2 != NULL);
	while(*str1 == *str2)
	{
    
    
		if(count == num ) break;
		if(*str1 == '\0')
			return 0;
		str1++;
	str2++;
	count++;
	}
	return *str1-*str2;
}

Guess you like

Origin blog.csdn.net/qq_74013365/article/details/134721079