当前位置:首页 > 公众号精选 > wenzi嵌入式软件
[导读]基本概念阐述memcpy和memmove都是C语言的库函数,相比于 strcpy和 strncpy只能针对于字符类型的数组(),这两个函数可以拷贝其他类型的数组,对于 memcpy和 memmove的区别是什么呢?这里,在Linux里通过 man命令查看两个函数的区别,查询的结果...

基本概念阐述

overflow-wrap: break-word;border-radius: 4px;background: rgb(248, 248, 248);">memcpymemmove都是 C 语言的库函数,相比于 strcpy和 strncpy只能针对于字符类型的数组(),这两个函数可以拷贝其他类型的数组,对于 memcpy和 memmove的区别是什么呢?这里,在 Linux 里通过 man命令查看两个函数的区别,查询的结果如下所示,首先是 memcpy函数的阐述。

image-20210729214558247
通过上述信息,可以知道,函数原型是:

void *memcpy(void *dest, const void *src, size_t n);
这个函数的功能如上面所说,就是复制src存储区域 n个字节到dest区域,并且srcdest的内存区域不能够重叠。

紧接着来看memmove函数,同样的,来看Linux里的帮助手册:

image-20210729234529864
通过上述信息,可以知道,对于memmove的函数原型是:

void *memmove(void *dest, const void *src, size_t n);
具体函数是什么意思呢?通过上图中的DESCRIPTION可以看到:

memmove() 函数将 n 个字节从内存区域 src 复制到内存区域 dest, 但是相比于memcpy函数不同的是,他的内存区域可能会重叠:复制的过程就好比是将 src 中的字节首先被复制到一个不重叠的临时数组中src 或 dest中,然后将字节从临时数组复制到 dest

实现 memcpy 和 memmove及原理介绍

关于前面所叙述的内存重叠的情况,会出现哪些问题呢?在论述这个问题之前,我们先来自己实现 memcpy 和 memmove 函数,当然自己实现的大多数情况是没有库实现的那么严谨和完备的。首先是memcpy函数的实现:

void *memcpy(void *dest, const void *src, size_t count)  
{  
    if(dest == NULL || src == NULL || count <= 0)  return NULL;  
    char *d = (char *)dest;  
    char *s = (char *)src;  
    while(count--)  
    {  
        *d  = *s ;  
    }  
    return dest;  
}  
代码很容易理解,就不在这里进行赘述了,其中,有一点也是笔者自己以前容易遗忘的一点,就是函数入口处对参数进行检查,不然会发生意想不到的错误。

接下来就是 memmove函数的实现:

void *memmove(void *dest, const void *src, size_t count)  
{  
    if(dest == NULL || src == NULL || count <= 0)  return NULL;  
    if(dest < src)  
    {  
        char *d = (char *)dest;  
        char *s = (char *)src;  
        while (count--)  
        {  
            *d  = *s ;  
        }  
    }  
    else  
    {  
        char *d = (char *)dest   count;  
        char *s = (char *)src   count;  
        while (count--)  
        {  
            *--d = *--s;  
        }  
    }      
    return dest;  
}  
memmove 函数要相比于 memcpy函数的实现要复杂一点点:分成了目的地址在前还是在后两种情况,如果是目的地址在前,那么就必须将src地址所在的字符串从前往后拷贝,反之,则必须将src所在的字符串从后往前拷贝。

如何解释这一原因呢,我们从一个例子说起,下面是对应的代码:

int main(int argc, char **argv) 
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int i = 0;
    my_memcpy(arr   2, arr, 20);

    for (i = 0; i < 10; i ) 
    {
        printf("%d ", arr[i]);
    }

    return 0;
}
可以看到代码所实现的功能是,将arr数组中12345拷贝到 34567所在的地址中去,按照这样一个思路,因该输出的是:

1 2 1 2 3 4 5 8 9 10
但是程序运行后输出的是:

1 2 1 2 1 2 1 8 9 10
这是为什么呢?笔者这里来图解一下:

image-20210730003005350
首先,将src地址的值赋值给dest,然后指针后移动,继续下一次的赋值,此时数据就发生了变化,如下图所示:

image-20210730003025398
可以看到,此时 3 的位置变成了 1,继续移动指针,也就有了如下的变化:

image-20210730003207597
我们依据此原理,最后再移动三次指针,也就是如下所示的变化:

image-20210730004153026
最终也就得到了上述的结果。

这种情况也就是dest在后,然后src在前的一种情况,如果是从前往后拷贝的话,也就会造成上述的问题,而解决的办法就是从后往前拷贝,具体的过程,也如下图所示:

image-20210730005452356
可见,如果是此时 dest的地址在src的后面,那么就需要从后往前复制,这样才不会导致数据覆盖掉。

额外注意的一点,上文也提到了,就是说,对于 memmove 也不是一概而论的,如果是 dest的地址在前面,那么也还是需要从前往后复制才行。

至此,关于 memmove和 memcpy 的内容就叙述完啦~


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

(全球TMT2022年2月23日讯)Nova宣布在中国建立新的本地公司实体,并在上海开设新的中国总部。近年来,Nova在中国的业务显著增长,服务于该地区半导体行业的扩张。新设施是Nova强化全球网点战略的组成部分,该战...

关键字: ov

呼吁年轻人才加入他们的虚拟合唱团 美国旧金山2022年2月16日 /美通社/ -- 才...

关键字: ov

北京2022年1月25日 /美通社/ -- 全球领先的图像级激光雷达提供商Innovusion与自动驾驶头部公司蘑菇车联宣布,双方正式达成战略合作。未来三年里,双方将基于各自前瞻性的技术优势与深厚的资源布局,围绕自动驾驶...

关键字: 进程 自动驾驶 ov

(全球TMT2022年1月26日讯)图像级激光雷达提供商Innovusion与自动驾驶头部公司蘑菇车联宣布,双方正式达成战略合作。未来三年里,双方将基于各自前瞻性的技术优势与深厚的资源布局,围绕自动驾驶、车联网及其他业...

关键字: 激光雷达 自动驾驶 ov

苏州2022年1月4日 /美通社/ -- 全球领先的图像级激光雷达提供商Innovusion在2022年国际消费电子展上,将展出其即将量产并搭载于蔚来首款旗舰轿车ET7上问世的图像级超远距激光雷达猎鹰(Falcon)。与...

关键字: 激光雷达 ov

(全球TMT2022年1月5日讯)图像级激光雷达提供商Innovusion在2022年国际消费电子展上,将展出其即将量产并搭载于蔚来首款旗舰轿车ET7上问世的图像级超远距激光雷达猎鹰(Falcon)。与此同时,Inno...

关键字: 激光雷达 ov

香港2021年12月14日 /美通社/ -- 亚洲一般保险领导者中银集团保险有限公司、国际保险精算咨询公司Milliman携手企业级保险技术平台CoverGo,共同简化中银集团保险的车险生态系统和客户体验。 中银集团保...

关键字: ov

(全球TMT2021年11月4日讯)11月3日上午,激光雷达提供商图达通智能科技(苏州)有限公司 (Innovusion) 举办了一场热烈且激动人心的开业庆典。庆典仪式在Innovusion位于苏州高铁新城长三角国际研...

关键字: ov

UVM factory允许一个类在构造时被派生类替换。这对于更改testbench的行为很有用,它将一个类替换为另一个类,而无需编辑或重新编译testbench代码。为了使factoryoverride发挥作用,需要遵循...

关键字: ov

来源:blog.csdn.net/lizeyang/article/details/40040817为了避免空指针调用,我们经常会看到这样的语句。...if (someobject != null) {    someo...

关键字: ov
关闭
关闭