首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【CC++】为什么不都用memmove代替memcpy

在知乎看见一个比较好的问题,整理下分享给大家。 memmove相比memcpy增加了内存重叠的判断,更加安全,效率只是差了那么一丢丢, 为什么经常看见memcpy, 很少看见memmove 呢 ?...(加粗是我加的) 当然他这是从库函数的角度来说,他觉得从一开始就干脆搞成memcpy就是memmove,然后就没这么多毛病了。 另外有人质疑说到底性能差多少。...Linus的Argument是memmove就比memcpy多一条判断指令。 我来换句话说,如果反正地址是不重叠的,那么memmove一定可以写成if (地址不重叠) memcpy();的形式。...举证几点: Linus 曾经谈过这个话题, @杨个毛的答案中已经完整引述了。 Windows 的 C 运行库(msvcrt)里,memcpy 实际上是 memmove 的 alias。...另,现在很多 Linux 发行版已经在 gcc 中默认把 _FORTIFY_SOURCE 给打开了,它给很多函数增加额外的安全检查,例如 memcpy(dst, src, n) 会被替换成 __memcpy_chk

81530

轻松拿捏C语言——【内存函数】

C语言中的内存操作函数:memcpy, memmove, memset, memcmp 在C语言中,我们经常需要对内存块进行各种操作,比如复制、移动、设置值以及比较。...C标准库提供了四个非常有用的函数来处理这些操作:memcpy, memmove, memset, memcmp 下面我将逐一介绍这些函数及其用法。...1. memcpy() 用于从源内存块复制指定数量的字节到目标内存块。这个函数不检查源内存和目标内存是否重叠,因此如果重叠,它可能会导致未定义的行为。...函数原型❤️ void *memcpy(void *dest, const void *src, size_t n); dest:指向目标内存块的指针。 src:指向源内存块的指针。...memmove也具有memcpy的功能 函数原型 void *memmove(void *dest, const void *src, size_t n); 参数与 memcpy() 相同。

10010
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    内存函数memcpy和memmove详解及模拟实现

    前言:                      大家好,我学习完memmove函数后做了如下一些总结,和大家一起探讨交流,如有错误和遗漏欢迎大家在评论区指出。...介绍memmove函数:           君子性非异也,善假于物也。想要了解一个函数,首先可以利用工具,了解它的基本用法 这里我用www.cplusplus.com这个网站进行查找。...我们可以先了解一下memcpy,同样通过上面的网站查找: 不难发现,这两个函数的差别好像不大 其实 标准值规定: memcpy来实现不重叠的内存拷贝; memmove来实现重叠的内存拷贝。...模拟实现memcpy:     由浅入深,我们先来模拟不重叠的内存拷贝也就是模拟memcpy: 先准备两个数组,写一个打印数组的函数: #include void print(int...arr[], int sz)//打印数组的函数 { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } } int

    15310

    手把手教你玩转内存函数(含模拟实现)

    一、memcpy 1.认识memcpy 以下关于函数定义的图片均出自:cplusplus.com - The C++ Resources Network memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝...所指向地址的20个字节 for (int i = 0; i < 10; i++) { printf("%d ", arr1[i]); }//将修改之后的数组打印出来 } 3.拓展:模拟实现memcpy...首先我们要明确我们这个函数要实现的目标,它的目标是将dest所指向地址的20个字节一个一个转换为src所指向地址的20个字节 那么我们的参数得有两个地址,这样才能访问dest和src所指向的内容并通过地址一个字节一个字节的访问...拷贝到6,7上呈现出来的就会是这般 3.拓展:模拟实现memmove 核心问题已经说出来了,接下来就提一下解决方案,很简单,我们不难看出,有问题的其实就在重叠的部分,这里我直接说结论了,我们得先将重叠部分给拷贝到目标上再将其他的部分拷贝到目标上才是合理的...,num为它们比较的字节个数 举个例子,如果我要比较两个整型数据,我就要传两个整型地址,同时还要传一个大小为4的整型变量(或者说无符号整型),如此才能够通过一个字节一个字节的比较从而得知是哪个整型大

    36610

    【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)

    当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会将对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。...,perror函数相当于⼀次将上述代码中的第9⾏完成了,直接将错误信息打印出来。...perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。...,肯定不可能只有字符串,所以C语言提供了一些内存函数,可以操作内存块,以下介绍常用的四个: 内存函数 memcpy使用和模拟实现 1 void * memcpy ( void * destination...\n", buffer1, buffer2); return 0; } 以上就是关于字符和字符串以及内存函数详细介绍(下篇)的内容啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力

    10910

    C语言中常见的内存函数

    kw=memcpy memcpy这个函数作用: 从source指向的位置开始复制num个字节的数据到destination指向的内存中。...下面是这个函数使用的一个例子: memcpy的模拟: 我们可以参照cplusplus官方memcpy函数的格式进行模拟。 如下: 这个函数的模拟并不难,不过多讲解。...二.memmove(内存移动) 当我们了解了memcpy函数后,我们来思考下这个问题? 如果dest与src有重叠,我们模拟的memcpy函数还能起作用吗? 答案是不能。...kw=memmove这个函数的作用跟memcpy函数相似,只不过是专门解决重叠拷贝的情况。...使用例子: memmove函数的模拟: 当dest src时,我们采取顺序打印(以src的视角)不然重叠的部分会被覆盖。 当dest > src时,我们采取逆序打印。

    5010

    【字符串+内存函数的介绍】

    (可打印) isgraph 任何图形字符 isprint 任何可打印字符,包括图形字符和空白字符 大小写字母转换函数: int tolower ( int c ); int toupper...而模拟实现的my_memcpy才是memcpy真正的逻辑原理,因此,memmove还是非常必要的 3.7 模拟实现memmove 还以上面arr1数组为例,由于dest>src,故我们可以从右往左拷贝...实现一道典型题目 这个分支是我后续加上的(2022.7.25),因为我突然想到了一个新的方法来实现这道题目。...在此之前,可以用两种方法实现,今天之后,就变成三种了: 指针数组 两步翻转 strtok辅助实现 1.指针数组 那先来介绍第一种,这也是我刚接触到这道题第一反应想到的方法: 思路是通过记住每一个单词的首地址...5.总结: 通过对以上函数的了解,对于字符数组的操作以及内存类的函数会变得得心应手,要用其功能必先了解其原理。那么,这篇文章就到这里,码字不易,你们的支持将是我前进的不竭动力!

    76300

    字符串与内存函数的介绍+模拟实现

    (可打印) isgraph 任何图形字符 isprint 任何可打印字符,包括图形字符和空白字符 字符转换函数 函数 功能 tolower 将大写字母转换为小写字母 toupper 将小写字母转换为大写指针...: //i am a student 1.11 memcpy void* memcpy(void* destination,const void* source,size_t num); 函数memcpy...*src) return dest;//如果src是空的,就直接返回dest就可以了 //利用3指针,定义3个指针,两个指向dest,一个指向src //指向dest的指针其中一个为保存返回位置的起始地点的指针...src; for(int i = 0;i<num;++i) { *p1 = *p2; p1+=1; p2+=1; } return dest; } C语言规定:memcpy只需要实现不重叠的拷贝就可以了...但是vs上memcpy函数实现了重叠拷贝,所以你在vs上让memcpy处理重叠的拷贝也是没问题的,只是不能保证所以的编译器都会这么设计。

    8010

    【C语言】字符串函数+内存操作函数

    版的strncpy函数,memcpy就是能操作不同类型数据的拷贝了) 1.12 memmove函数(PLUS版memcpy) void * memmove ( void* destination, const...ret指针变量 { printf("%s\n", ret); } 1.for循环第一部分的代码只会被调用一次,很好解决了,我后续传空指针的重复步骤 2.for循环执行完初始化的部分后,会一直循环第二部分和第三部分的步骤内容...图片分割线 通过上面的这两张图片我们可以看出,当内容溢出时,我们的strncpy函数是不会给你添加\0的,所以当printf函数打印时,无法找到\0就会打印出来乱码,出现了越界访问的程序错误 9....这里的代码实现我们也还是延续了之前memcpy的想法,就是一个字节一个字节的拷贝,而且由于src和dest位置的大小不同,我们实现代码的方式也是不同的,所以也要进行if和else的分支语句判断 13.内存函数...memmove函数功能更加强大一些,它可以包括memcpy函数的功能 对于memset和memcmp函数我们只介绍了他的用法,并没有具体的模拟实现。

    94120

    【C进阶】——内存操作函数memcpy、memmove、memcmp、memset详解及其模拟实现

    1.内存块拷贝函数——memcpy 我们一起来认识一下: 1.1 函数介绍 看到memcpy的参数,大家有没有感到似曾相识呢?...变量的大小)的内容拷贝到arr1中 1.2 memcpy的模拟实现 我们已经明白这个函数是怎么工作了,那现在我们就来模拟实现一下memcpy。...我们已经测试过了,用我们模拟实现的my_memcpy是不行的,因为在从前向后拷贝的时候后覆盖掉4,5。 既然从前向后拷贝不行,那我们从后向前拷会不会就可以了呢?...其实对比上面两次出现的情况,我们可以发现: 注:数组随着元素下标的递增地址是从小到大的。 当源空间的起始地址dest小于目标空间的起始地址src时,我们需要从前向后拷贝。...当源空间的起始地址dest大于目标空间的起始地址src时,我们需要从后向前拷贝。 那我们就可以模拟实现memmove了。

    55910

    C语言进阶(五)——字符串+内存函数的介绍

    第二次传参为NULL,我们进行 strtok(NULL,p),此时的NULL虽然传了一个空指针,但是指向了上一次保存的分隔符的位置。从这个位置开始,将下一个分隔符.,改为\0。...在这里,我们引入内存操作函数的概念,我们直接对数据的内存进行操作。 1.memcpy函数的介绍和模拟实现 (1)memcpy函数的功能 ? ?...(3) memcpy函数的模拟实现 void * my_memcpy(void * dest, void * src, int num) { char*ret = (char *)dest; while...(4)memcpy函数的缺点 现在有一个要求: ? ?   所以,我们并不能按照我们的要求打印,内存相互重叠的情况下,内存的数字会发生改变。...而在memmove 函数中则完美的解决了这个问题(内存重叠)。

    56250

    内存函数(C语言)

    内存函数 以下函数的头文件:string.h 针对内存块进行处理的函数 memcpy 函数原型: void* memcpy(void* destination, const void* source,...,这个memcpy函数是一个函数参数,函数返回类型都是void无符号类型,这是说明该函数是一个,泛型函数,它可以接收任意类型的参数,使同一个函数能用于多种类型的数据。...) = *((char *)src );,其代码内讲多块内容合并在一起操作,通过控制num大小,来控制了dest和src偏移的位置,而循环结束的条件的num为0,这样就有了一条很精简的代码。...09 09实际上是16进制数,0x09090909,所以在打印的结果上会很大。...这里以字符串为例,字符串的大小是一个字节,这里我试图将字符数组arr1里的前三个字节内容置为x。

    3700

    内存函数的学习

    ()强制转换操作符并不会永久改变原本的变量类型。 第二个 \0在打印时不会显示出来  第三个   void *能接收任意类型指针,除了被const修饰的指针类型。...有人在vs2022用memcpy对有重叠内存的参数进行拷贝,但是正常结果,这并不代表memcpy本身有能对重叠内存的参数进行拷贝的功能,而是vs2022使memcpy能实现该功能,在其他编译器就不一定了...memcpy的模拟实现 void * memcpy ( void * dst, const void * src, size_t count) { void * ret = dst; assert(...memmove 其格式和memcpy一模一样  其实可以理解memmove为高配的memcpy,当其不重叠时,可以实现,当其重叠时依然可以实现。 而memcpy只能实现不重叠的,重叠的不能实现。...\n", buffer1, buffer2); return 0; }  总结 这就是我们的内存函数 ,其头文件都为#include.到这里,我们就讲了四个内存函数,都是以字节为单位去作用

    9010

    C语言: 详解常用的字符串函数(使用+模拟实现)

    字符分类函数​ 2.1 memcpy 2.2 memmove​​​​​​​ ---- 前言: C语言中,字符串函数和字符函数的使用是很频繁的,如果我们能够熟练使用,能够帮助我们解决很多的字符问题。...(不包括 ‘\0’) 参数指向的字符串必须要以 ‘\0’ 结尾,不然结果就是未知的了。 函数的返回值是 size_t 类型,是无符号的。...ch = 'a'; if (isalpha(ch)) { printf("%c\n", toupper(ch)); } return 0; } 打印结果:A 2.1 memcpy 格式:memcpy...( void * destination, const void * source, size_t  num ) 函数memcpy从source的位置开始向后赋值num个字节的数据到destination...2.2 memmove 格式:memmove( void *dest, const void *src, size_t count ) 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的

    79920
    领券