[C language simulation to implement memcpy function, memcpy function]

C language programming notes—027

  • Simulation implementation of memcpy function and memcpy function in C language
    • 1. Introduce the memcpy function
      • 1.1. Simulate and implement the memcpy function
    • 2. Introduce the memmove function
      • 2.1. Simulate and implement the memmove function
    • 3. Conclusion

C language simulation implementation of memcpy function, memcpy function

Foreword:
Through the knowledge of C language memory functions, this article will provide in-depth knowledge of the underlying principles of the memcpy function and memcpy function, and simulate the implementation of the corresponding functions.

/Summary of knowledge points/
Memory related functions
1.memcpy –strcpy
2.memmove
3. memset
4.memcmp – strcmp

1. Introducing the memcpy function

Function prototype: void *memcpy( void dest, const void src, size_t count); —- void description, compatible with any type
Function function: Copy the data from the source memory to the target memory, and the return value type is void

Header file:
Usage Notes:
(1). Different from strncpy, the parameters num and count. One refers to the number of elements that need to be copied, and the other refers to the byte size of the elements that need to be copied.
(2) Compared with the strcpy function, which only operates on strings for copying, memcpy does not just operate on characters.
The sample code is as follows:

#include <stdio.h>
#include <string.h>
int main()
{<!-- -->
int arr1[10] = {<!-- --> 0 };
int arr2[] = {<!-- --> 1,2,3,4,5 };
memcpy(arr1, arr2, 20);//20 == 4*5
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i + + )
{<!-- -->
printf("%d ", arr1[i]);
}
return 0;
}

1.1. Simulation and implementation of memcpy function

#include <stdio.h>
#include <string.h>
#include <assert.h>
//Note: void* cannot perform arithmetic operations
//In addition, (char*) must be used here to operate, because if it is other types, it will cause problems such as data loss --- Lenovo is similar to qsort and operates byte by byte.
void* my_memcpy(void* dest, const void* src, size_t sz)//How many bytes will sz copy?
{<!-- -->
assert(dest & amp; & amp; src);
while (sz--)//Copy byte by byte
{<!-- -->
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;//Note: Forced type conversion has temporary attributes, so (char*)dest + 1 is needed to assign and save data, and dest + + cannot be used
src = (char*)src + 1;
}
}
int main()
{<!-- -->
int arr1[10] = {<!-- --> 0 };
int arr2[] = {<!-- --> 1,2,3,4,5 };
my_memcpy(arr1, arr2, 20);//20 == 4*5
for (int i = 0; i < 5; i + + )
{<!-- -->
printf("%d ", arr1[i]);
}
return 0;
}

Explanation:
1.assert is an assertion, and the parameters are pointers, which prevents the passed parameters from being null pointers and avoids the problem of wild pointers.
2. Use a pointer variable to always save the starting address of the target string to prevent the target starting address from changing, causing the function’s return value to be incorrect.
3.sz – Because memcpy copies in bytes, in order to be compatible with multiple types, it needs to be converted to char* type before operation. (You can review the previous chapter and simulate the content of the qsort function)

Extension: memcpy operation problem on the same memory space
Using our own simulated memcpy function, the cause of the problem is:
Debugging shows that it is copied byte by byte.
So for example: copying 0x11223344 to 01 results in 0x01010101, which cannot meet our expectations.
And we expected it to be 0x11223301, and then the next element would be 0x11224401
However, the memcpy library function makes up for this error problem under the current compiler conditions. It shows that the author of the library function is very comprehensive and at the same time more complex.

2. Introducing the memmove function

Function prototype: void *memmove( void dest, const void src, size_t count);
Function: Transfer data from source memory. Copy to the target memory, and compared with memcpy, it can copy data in the same space. The return value type is void

Header file:
Usage Notes:
(1), memcpy can only operate on data between memories in different spaces.
That is: to copy non-overlapping memory, you can use memcpy, while for overlapping memory spaces, you need to use the memmove function.
The sample code is as follows:

#include <stdio.h>
#include <string.h>
int main()
{<!-- -->
int arr1[10] = {<!-- --> 0 };
int arr2[] = {<!-- --> 1,2,3,4,5 };
memmove(arr1, arr2, 20);//20 == 4*5
int sz = sizeof(arr1) / sizeof(arr1[0]);
for (int i = 0; i < sz; i + + )
{<!-- -->
printf("%d ", arr1[i]);
}
return 0;
}

2.1. Simulation and implementation of memmove function

#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t sz)
{<!-- -->
assert(dest & amp; & amp; src);
char* ret = (char*)dest;
if (dest < src)//Copy from front to back
{<!-- -->
while (sz--)
{<!-- -->
*((char*)dest) = *((char*)src);
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else//Copy from back to front
{<!-- -->
while (sz--)//sz-- Use it first and then subtract, that is, first judge that sz=20 is true, then subtract 1 after use to enter the loop, at this time sz=19
{<!-- -->
*((char*)dest + sz) = *((char*)src + sz);
}
}
return ret;
}
int main()
{<!-- -->
int arr[10] = {<!-- --> 1,2,3,4,5,6,7,8,9,10};
my_memmove(arr + 2, arr, 20);//20 == 4*5
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i + + )
{<!-- -->
printf("%d ", arr[i]);
}
return 0;
}

Explanation:
1.assert is an assertion, and the parameters are pointers, which prevents the passed parameters from being null pointers and avoids the problem of wild pointers.
2. Use a pointer variable to always save the starting address of the target string to prevent the target starting address from changing, causing the function’s return value to be incorrect.
3.dest < src means that the target space address is in front of the source address, and it is suitable to copy from the high bit of the source address, that is, copy from front to back.
It is worth noting that because memmove copies in bytes, in order to be compatible with multiple types, it needs to be forced to the char* type before operation. (You can review the previous chapter and simulate the content of the qsort function)
4. Otherwise, the target space address is behind the source address, and it is suitable to copy from the low bit of the source address, that is, copy from back to front.
It is worth noting that the last data address for the source address is pointer + sz offset from back to front.

Summary:
1.memcpy can only operate on data between memories in different spaces.
That is: to copy non-overlapping memory, you can use memcpy, while for overlapping memory spaces, you need to use the memmove function.
2. Library functions can be implemented, and the standard stipulates:
Use memcpy to copy non-overlapping memory, and the requirement is to reach 60
Use memmove to copy overlapping memory
3. However, it is found that under the current compilation environment, memcpy can also realize the copy of overlapping memory, which far meets the requirements of 60 points and 100 points. Therefore, it is related to the compilation environment. It is recommended that the corresponding functions be implemented by suitable functions.

3. Conclusion

The most practical way to learn functions is to simply implement some similar functions with your own logic
As soon as half an acre of sugar cubes are opened, the skylight and cloud shadows linger together.
Ask where the canal can be so clear? Because there is a source of living water. -Zhu Xi (feelings after reading the book)