memcpy和memmove的区别及实现

简介: memcpy和memmove的区别及实现

我们先上定义

image.png

编辑

作用:将 num 字节的值从source所指向的位置复制到destination所指向的内存块。

image.png

编辑

作用:将 num 字节的值从source所指向的位置复制到destination所指向的内存块。

image.png

编辑

作用:将 num 字节的值从source所指向的位置复制到destination所指向的内存块。复制站的内容和使用中间缓冲区一样时,允许destination和source重叠。

memmove和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

我们用图来解释:

先用memcpy

image.png

编辑

在复制的过程source会和destination的一部分重叠并且覆盖掉destination的内容

下面memmove

image.png

两个对比的看在abc(de)这里发生了重叠,memmove的作用就是防止将重叠的部分覆盖,在拷贝的时候还在拷贝原来位置上对应的内容,而memcpy直接将其覆盖并且拷贝。

接下来我们实现两个函数

实现memcpy

void* my_memcpy(void* dst, const void* src, size_t cont)
{
  assert(dst);
  assert(src);
  void* ret = dst;
  while (cont--)
  {
    *(char*)dst = (*(char*)src);
    dst = ((char*)dst)++;
    src = ((char*)src)++;
  }
  return ret;
}

image.png编辑

这个是memcpy函数的结构

我们的思想是将每个比特位的内容都交换,这样可以做到对应num字节的内容交换,所以我们将dst和src强转为char*类型,这样每次我们可以选择一个比特位的内容进行操作交换,移动。(这里先要吧dst的首地址记录下来作为返回值)

实现memmove

image.png

编辑

void* my_memmove(void* dst, const void* src, size_t count)
{
    void* ret = dst;
    if (dst <= src || (char*)dst >= ((char*)src + count))
    {
        while (count--) {
            *(char*)dst = *(char*)src;
            dst = (char*)dst + 1;
            src = (char*)src + 1;
        }
    }
    else {
        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);
}

这个是memmove的结构

思想和memcpy一样,注意的是重叠内容的处理,我们分为两种情况;

1.没有重叠内容

这种情况为  dst <= src || (char*)dst >= ((char*)src + count) 这样两部分不会重叠

2.重叠情况

这时候我们只需要反过来,倒着拷贝就可以了(仔细想一下)

image.png

以上就是memcpy的memmove的内容,欢迎在评论区留言共同进步!!!

相关文章
|
Java 开发者 Spring
Spring Framework 中的 @Autowired 注解:概念与使用方法
【4月更文挑战第20天】在Spring Framework中,@Autowired 注解是实现依赖注入(Dependency Injection, DI)的一种非常强大的工具。通过使用 @Autowired,开发者可以减少代码中的引用绑定,提高模块间的解耦能力
1303 6
|
小程序 Java API
认证服务:整合短信验证码
认证服务:整合短信验证码
|
5月前
|
安全 Java 编译器
Java 校招面试题目合集及答案 120 道详解
这份资料汇总了120道Java校招面试题目及其详细答案,涵盖Java基础、JVM原理、多线程、数据类型、方法重载与覆盖等多个核心知识点。通过实例代码解析,帮助求职者深入理解Java编程精髓,为校招面试做好充分准备。无论是初学者还是进阶开发者,都能从中受益,提升技术实力和面试成功率。附带的资源链接提供了更多学习材料,助力高效备考。
251 3
|
Java 应用服务中间件 Maven
Maven的三种项目打包方式——pom,jar,war的区别
Maven 提供了多种打包方式,分别适用于不同类型的项目。pom 用于父项目或聚合项目,便于项目的结构和依赖管理;jar 用于Java类库或可执行的Java应用程序;war 则专用于Java Web应用程序的部署。理解这些打包方式的用途和特点,可以帮助开发者更好地配置和管理Maven项目,确保构建和部署过程的顺利进行。无论是单模块项目还是多模块项目,选择合适的打包方式对于项目的成功至关重要。
1721 3
|
存储 JavaScript 前端开发
decimal.js库的安装和使用方法
【10月更文挑战第24天】decimal.js 是一个非常实用的高精度计算库,通过合理的安装和使用,可以在 JavaScript 中实现精确的数值计算和处理。你可以根据具体的需求和项目情况,灵活运用该库来解决数字精度丢失的问题。
|
运维 负载均衡 算法
|
安全 调度
操作系统的心脏:深入理解内核态与用户态####
【10月更文挑战第14天】 本文旨在通过深入浅出的方式,探讨操作系统中两个核心概念——内核态(Kernel Mode)与用户态(User Mode),它们的区别、联系以及对计算机系统性能和安全的影响。不同于传统摘要的概括性介绍,本文将以一次虚拟的“旅行”为主线,带领读者穿越复杂抽象的技术迷雾,揭示这两种运行模式背后的秘密及其在现代计算中的重要性。
392 0
|
监控 Java 调度
使用Java实现高性能的定时任务调度
使用Java实现高性能的定时任务调度
|
存储 运维 NoSQL
|
缓存 监控 网络协议
面对ARP攻击,怎么做好主机安全,受到ARP攻击有哪些解决方案
ARP攻击的具体原理主要是基于ARP(Address Resolution Protocol,地址解析协议)的漏洞进行欺骗和攻击。ARP协议是TCP/IP协议族中的一个重要协议,用于实现IP地址到MAC地址的映射。然而,由于ARP协议在设计时缺乏必要的安全验证机制,使得攻击者有机会进行欺骗和攻击。