C Advanced: Memory Manipulation Functions

memory manipulation function

memcpy

Header file: string.h

Basic use: Make unrelated (non-overlapping memory) copies.

Function prototype: void* memcpy(void* destination,//pointer to target data

                                            const void* source, // pointer to the copied data

                                            size_t num);//The number of copies (unit: byte)

Note:

1. Basic principle: Copy num bytes of data backwards from the location of source to the memory location of destnation.

2. This function is different from strcpy, it will not stop when it encounters '\0'.

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

4. void* As mentioned before, in order to ensure universality, use void* to receive any type of data.

Example of use:

#include <stdio.h>
#include <string.h>

struct {
	char name[40];
	int age;
}person, person_copy;

int main()
{
	char myname[] = "Pierre de Fermat";
	
	memcpy(person.name, myname, strlen(myname) + 1);
	person.age = 46;

	memcpy(&person_copy, &person, sizeof(person));
	printf("person_copy: %s , %d\n", person_copy.name, person_copy.age);
	return 0;
}

This is an example of copying strings and struct member variables to another struct.

In order to better understand this function, let's simulate and implement it below.

void* my_memcpy(void* dest, const void* src, size_t num)
{
	//断言,防止dest或者src是空指针,如果是空指针则会报错
	assert(dest && src);
	//保存起始地址
	void* ret = dest;
	while (num--)
	{
		//一次用最小单位(字节)移动,保证泛用性
		*(char*)dest = *(char*)src;
		//注:强制类型转换只是临时的,后面+1操作时已不存在
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	//返回目标空间的起始地址
	return ret;
}

memmove

Header file: string.h

Basic use: copying of overlapping memory blocks .

Function prototype: void* memove(void* destination, const void* source, size_t num)

Note:

1. The difference from memcpy is that the source memory block and target memory block processed by the memove function can overlap.

2. If the original space and the target space overlap, you have to use the memmove function to deal with it.

Example of use:

#include <stdio.h>
#include <string.h>

int main()
{
	char str[] = "memmove can be very useful.....................";
	//将字符串中从第15个元素的位置向后数共11个字符挪到从第20个字符开始向后数第11个元素
	memmove(str + 20, str + 15, 11);
	puts(str);
	return 0;
}

A mock implementation of the function:

#include <stdio.h>
#include <string.h>
#include <assert.h>

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	//当目标位置地址小于源内存块数据地址时,采用从前向后拷贝的方式
	if (dest < src)
	{
		//根据字节数量一个一个移动内存单元
		while (num--)
		{
			*(char*)dest = *(char*)src;
			//向后移动一位
			dest = (char*)dest + 1;
			src = (char*)dest + 1;
		}
	}
	//当目标为指针大于源内存块数据地址时,采用从后向前的拷贝方式
	else if (dest > src)
	{
		//将dest和src指针定位到各自最后的内存地址处
		dest = (char*)dest + num - 1;
		src = (char*)src + num - 1;
		//根据字节数量一个一个移动内存单元
		while (num--)
		{
			*(char*)dest = *(char*)src;
			//向前移动一位
			dest = (char*)dest - 1;
			src = (char*)src - 1;
		}
	}
}

memcmp

Header file: stdio.h

Basic use: As the name suggests, similar to the strcmp function, this function compares the size of memory data (byte by byte).

Function prototype: int memcmp(const void* ptr1, const void* ptr2, size_t num);

Note:

1. Compare num bytes starting from ptr1 and ptr2

2. Similar to the return value of strcmp, the content of the first pointer is still greater than the content of the second pointer, and a number greater than zero is returned, and the content of the first pointer is smaller than the content of the second pointer, and a number smaller than zero is returned, which is equal. returns zero.

Basic example:

#include <stdio.h>
#include <string.h>

int main()
{
	char buffer1[] = "axxxxxxxxxxx";
	char buffer2[] = "bbbbbbbbbbbb";

	int n;
	n = memcmp(buffer1, buffer2, sizeof(buffer1));
	printf("%d", n);
	return 0;
}

result:

This blog is shared here, thank you all! !

 

Guess you like

Origin blog.csdn.net/asdssadddd/article/details/131866178