当前位置: 代码迷 >> 综合 >> 库函数:memcpy 和 memmove
  详细解决方案

库函数:memcpy 和 memmove

热度:97   发布时间:2023-12-23 00:01:56.0

memcpy 和 memmove

都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下:

void *memcpy(void *dst, const void *src, size_t count);void *memmove(void *dst, const void *src, size_t count); 

他们的作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。

举例说明

int arr[10] = {1,2,3,4,5,6,7,8,9,10}
当src指向1位置,dst指向3位置,当需要复制4个int也就是16个字节时,使用memcpy会造成覆盖问题。
原因:从前向后复制时,1会复制到3位置将还没拷贝的3覆盖为1。因此最后结果为:{1,2,1,2,1,2,7,8,9,10},而我们想要的结果为:{1,2,1,2,3,4,7,8,9,10}

  • 出现这种情况的原因就是我们从前向后复制会覆盖还未拷贝的信息,那么修改为从后向前复制即可。但是如果src在dst后面并且存在覆盖,从后向前也会造成覆盖问题。因此我们需要推导条件来选择复制方向。

当存在内存覆盖并且src(源地址)在dst(目标地址)之前,需要使用从后向前的拷贝。

if ((src < dst) && (char*)src + size > (char*)dst) //当然第二个条件可以不需要

具体实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dst, const void* src, size_t size) {
    char* psrc; //强转为了char会按照字节拷贝char* pdst;if (dst == nullptr || src == nullptr) {
    return nullptr;}//dst在src后面,并且拷贝区间和目标区间存在覆盖(覆盖前面内容),从后向前拷贝if ((src < dst) && (char*)src + size > (char*)dst) {
    psrc = (char*)src + size - 1;pdst = (char*)dst + size - 1;while (size--) {
    *pdst-- = *psrc--;}}else {
    psrc = (char*)src;pdst = (char*)dst;while (size--) {
    *pdst++ = *psrc++;}}return dst;
}void* my_emmove(void* dst, const void* src, size_t cnt) {
    if (dst == nullptr || src == nullptr) {
    return nullptr;}char* dstp = (char*)dst;const char* srcp = (char*)src;if (src < dst) {
    dstp += cnt - 1;srcp += cnt - 1;while (cnt--) {
    *dstp-- = *srcp--;}}else {
    while (cnt--) {
    *dstp++ = *srcp++;}}return dstp;
}int main(int argc, char* argv[])
{
    char buf[100] = "abcdefghijk";int arr[10] = {
     1,2,3,4,5,6,7,8 };int arr1[10] = {
     0 };//memcpy(buf+2, buf, 5);my_memcpy(arr + 2, arr, 16);printf("%s\n", buf);
}