首页 > 编程语言 >C++ memcpy、memmove

C++ memcpy、memmove

时间:2024-03-19 18:56:43浏览次数:25  
标签:count src memmove dst C++ char void memcpy

函数原型:

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

memcpy和memmove相同点:

  1. 都是用于从src拷贝count个字节到dest

memcpy和memmove区别:

如果目标区域和源区域有重叠的话:

  1. memcpy不能够确保源串所在重叠区域在拷贝之前被覆盖。
  2. memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后src内容会被更改,当目标区域与源区域没有重叠则和memcpy函数功能相同。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

Linux下的实现过程:

void* _cdec1 memcpy(void* dst, const void* src, size_t count) {
	void *ret = dst;
    // 注意, memcpy函数没有处理dst和src区域是否重叠的问题
    while (count--) {
	*(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }
    return (ret);
}

void _cdec memmove(void* dst, const void* src, size_t count) {
    void* ret = dst;
    if (dst <= src || (char *)dst >= ((char *)src + count)) {
        // 若dst和src区域没有重叠,则从起始处开始逐一拷贝
        while (count--) {
            *(char *)dst = *(char *)src;
            dst = (char *)dst + 1;
            src = (char *)src + 1;
        }
    }
    else {
        // 若dst和src 区域交叉,则从尾部开始向起始位置拷贝,这样可以避免数据冲突
        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);
}

标签:count,src,memmove,dst,C++,char,void,memcpy
From: https://www.cnblogs.com/love-9/p/18083692

相关文章

  • c++学习记录 STL—常用查找算法
    一、算法简介find               //查找元素find_if             //按条件查找元素adjacent_find       //查找相邻重复元素binary_search      //二分查找法count        ......
  • C++ kmalloc、kzalloc、vmalloc的区别
    1.kmalloc函数原型:void*kmalloc(size_tsize,gfp_tflags);kmalloc()申请的内存位于物理内存映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因为存在较简单的转换关系,所以对申请的内存大小有限制,不能超过128KB。较常用的flags(分配内存的方法):G......
  • 高质量C/C++编程指南
    目录        1、概述    本文档参考《高质量C++C编程指南》及自己的心得编写,如有侵权,立刻删除!2、编程指南2.1文章结构    每个C++/C程序通常分为两个文件。一个文件用于保存程序的声明,我们称之为头文件。另一个文件用于保存程序的实现,我们称......
  • c++线程池(二)——线程池优化
    文章目录概要整体架构流程技术细节小结概要增加扇入扇出:优化:子线程维护自己的本地队列分析:目前文章《线程池一》介绍了一个简单的线程池,存在多个线程同时访问一个任务队列Task,出现抢锁的情况,这样会存在一定的性能消耗,会导致有些没抢到任务的线程没事做,造成资源浪......
  • 06_C++多维数组
    多维数组,数组指针在二维数组上的应用。#include<iostream>#include<stdio.h>usingnamespacestd;intmain(){intarr[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};int(*p)[5]=arr;cout<<"*p:"<<*p<<endl......
  • 分月饼【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-分月饼中秋节,公司分月饼,m个员工,买了n个月饼,m<=n,每个员工至少分1个月饼,但可以分多个,单人分到最多月饼的个数是Max1,单人分到第二多月饼个数是Max2,Max1-Max2<=3,单人分到第n-1多月饼个数是Max(n-1),单人分到第n多月饼个数是Max(n),Max(n-1)–Max(n)<=3,问有多少......
  • C++实现欧拉筛法
    Euler筛法介绍以筛出100以内(含100)的所有素数为例来说明一下欧拉筛法的原理。和Eratosthenes筛法一样,Euler筛法也从2开始筛,但Eratosthenes筛法会把2的倍数一批全部筛掉,而Euler筛法用2筛时仅仅把2*2(即4)筛掉,而把其它偶数留到后面再筛掉,从而避免了一个偶数被多次筛除带来的性能开销,......
  • C++STL第五篇(链表List的使用方法)
    list链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。相......
  • C++刷题杂记
    目录C++中如何声明二维vectorC++中如何声明二维vector在C++中,你可以使用嵌套的std::vector来声明一个二维的vector。每个元素本身是一个std::vector,而这些元素的集合构成了外部的std::vector。以下是如何声明一个二维vector的示例:#include<vector>intmain(){//声......
  • C++类实现顺序表
    环境:vscodesequencelist.h#ifndefSEQUENCELIST_H#defineSEQUENCELIST_H#defineMAXSIZE20//最大存储容量typedefintElemType;classSqList{public:SqList();//SqList(ElemTypeelems[],intn);//有参构造器~SqLis......