精华内容
下载资源
问答
  • memcpy 实现

    千次阅读 2010-05-07 18:11:00
    http://hi.baidu.com/new_christ/blog/item/f4c547433b0007149213c692.html 后面那个变态的没看懂,转过来有时间细读 第一种:最常见的:void* memcpy( void* dest, const void* src, size_t count ){if (count{pr

    http://hi.baidu.com/new_christ/blog/item/f4c547433b0007149213c692.html

     

    后面那个变态的没看懂,转过来有时间细读

     

    第一种: 最 常见的:

    void* memcpy( void* dest, const void* src, size_t count )
    {

    if (count<0)

    {printf("Invalid count number !./n");

    return (void*)0;}

    if(src==NULL||dest==NULL)

    return (void*)0 ;

    if ((unsigned int)dest==(unsigned int)src)

    {printf("The source is equal with the destanation!./n");

    return dest;}

        char* d = (char*)dest;
        const char* s = (const char*)src;
    while(count--)
         *d++ = *s++;
        return dest;
    }

    另一个实现,和上面类似,转贴高 质量C++/C编程指南 中的,供参考:

     

             void *memcpy(void *pvTo, const void *pvFrom, size_t size)

    {

            assert((pvTo != NULL) && (pvFrom != NULL));     // 使用断言

            byte *pbTo = (byte *) pvTo;     // 防止改变pvTo的地址

            byte *pbFrom = (byte *) pvFrom; // 防止改变pvFrom的地址

            while(size -- > 0 )

                *pbTo ++ = *pbFrom ++ ;

            return pvTo;

    }

    第二种: 转自变态之MEMCPY

    void* mymemcpy( void* dest, const void* src, size_t count )
    {
        char* d = (char*)dest;
        const char* s = (const char*)src;
        int n = (count + 7) / 8; // count > 0 assumed

        switch( count & 7 )
        {
        case 0: do { *d++ = *s++;
        case 7:        *d++ = *s++;
        case 6:        *d++ = *s++;
        case 5:        *d++ = *s++;
        case 4:        *d++ = *s++;
        case 3:        *d++ = *s++;
        case 2:        *d++ = *s++;
        case 1:        *d++ = *s++;
                   } while (--n > 0);
        }

        return dest;
    }
    解释:摘自原 贴:

    int n = (count + 7) / 8;计算要复制的轮数(每轮复制8位),剩下的余数位数也要复制进去。
    count & 7控制要复制余数位数,while (--n > 0)控制轮数。
    比如count = 9,则n = 2,count & 7 = 1,要复制2轮,程序跳到case1执行,复制一位之后,再循环一轮,复制8位.

    为何这么实现: 引用上面帖子后面的评论:

    每8个字节拷贝省7个跳转(AMD处理器内部分支预测算法是“假定全都跳转”,因此这里也就是相当于省了7个时钟周期);把swith和do循环凑 到一起,多少省几个字节的空间……
    但使用32位或64位指令,可以得到更大的优化效果,代码还要精炼得多。
    说实在话:除非内存小到极 点、并且无法增加的系统,写出这样的程序纯属作孽……

    后记: 一般出题目 让你实现memcpy,个人理解,其意图至少有以下几点:

    1.写任何程序都能反映出你的代码风格.

    2.考查你是否注意到,要拷贝的源,即const void* src,应该是用const的,避免有意或无意的修改.

    3.考查你,不应该直接对src和dst指针进行类似++或--之类的操作,而应该另外申请对应变量用于此操作.

    4.指针的类型转化问题,原始参数应该是void *的,你具体操作的时候,应该是转化为某种具体的类型,此处用char比较适合.

    5.注意要判断源src是否和dest重复,如果重复,直接返回或返回错误.

    6.应该还有其他考虑,如果以后想到,再补充.

    补充:后来又重新看了高 质量C++/C编程指南 ,其中,原作者直接对const char *strSrc和strDest进行++操作

    char *strcpy(char *strDest, const char *strSrc);

    {

        assert(( str Dest!=NULL) && ( strSrc !=NULL));   // 2分

        char *address = str Dest;                     // 2分

        while( (* str Dest++ = * strSrc ++) != /0 )     // 2分

           NULL ;

        return address ;                           // 2分

    }

    此时我才注意到,自己总结的上面第三点,是错误的,因为const char *strSrc 中的const是 指字符串内容为const,而不是说strSrc是const的,如果要指定strSrc是const,应该写成 char * const strSrc 。

    不过,对此,有人也许又该问了,那此处对strSrc进行++操作,不是破坏了原先strSrc的指向了吗?

    如果你真是这么问,那么说明你的概念还不是很清楚(我开始也是和你犯了同样错误),实际上这点在高 质量C++/C编程指南 ,也有提及,因为strSrc是函数的形参,而此处虽然对形参的进行++ 操作,改变其指向,但是并没有改变原始属性为const的字符串,而且此处的形参,在函数调用结束之后,也就释放了,对原始传来的地址,没有任何影响。

    展开全文
  • memcpy实现

    千次阅读 2010-04-07 23:43:00
    第一种:最常见的:void* memcpy( void* dest, const void* src, size_t count ){if (count{printf("Invalid count number !./n");return (void*)0;}if(src==NULL||dest==NULL)return (void*)0 ;if ((unsign

     

    第一种:最常见的:

    void* memcpy( void* dest, const void* src, size_t count )
    {

    if (count<0)

    {printf("Invalid count number !./n");

    return (void*)0;}

    if(src==NULL||dest==NULL)

    return (void*)0 ;

    if ((unsigned int)dest==(unsigned int)src)

    {printf("The source is equal with the destanation!./n");

    return dest;}

        char* d = (char*)dest;
        const char* s = (const char*)src;
    while(count--) 
         *d++ = *s++;
        return dest;
    }

    另一个实现,和上面类似,转贴高质量C++/C编程指南中的,供参考:

     

             void *memcpy(void *pvTo, const void *pvFrom, size_t size)

    {

            assert((pvTo != NULL) && (pvFrom != NULL));     // 使用断言

            byte *pbTo = (byte *) pvTo;     // 防止改变pvTo的地址

            byte *pbFrom = (byte *) pvFrom; // 防止改变pvFrom的地址

            while(size -- > 0 )

                *pbTo ++ = *pbFrom ++ ;

            return pvTo;

    }

     

    第二种:转自变态之MEMCPY

    void* mymemcpy( void* dest, const void* src, size_t count )
    {
        char* d = (char*)dest;
        const char* s = (const char*)src;
        int n = (count + 7) / 8; // count > 0 assumed  没有检查count为0的情况

        switch( count & 7 )
        {
        case 0: do { *d++ = *s++;
        case 7:        *d++ = *s++;
        case 6:        *d++ = *s++;
        case 5:        *d++ = *s++;
        case 4:        *d++ = *s++;
        case 3:        *d++ = *s++;
        case 2:        *d++ = *s++;
        case 1:        *d++ = *s++;
                   } while (--n > 0);
        }

        return dest;
    }
    解释:摘自原贴:

    int n = (count + 7) / 8;计算要复制的轮数(每轮复制8位),剩下的余数位数也要复制进去。
    count & 7控制要复制余数位数,while (--n > 0)控制轮数。
    比如count = 9,则n = 2,count & 7 = 1,要复制2轮,程序跳到case1执行,复制一位之后,再循环一轮,复制8位.

    为何这么实现:引用上面帖子后面的评论:

    每8个字节拷贝省7个跳转(AMD处理器内部分支预测算法是“假定全都跳转”,因此这里也就是相当于省了7个时钟周期);把swith和do循环凑到一起,多少省几个字节的空间…… 
    但使用32位或64位指令,可以得到更大的优化效果,代码还要精炼得多。 
    说实在话:除非内存小到极点、并且无法增加的系统,写出这样的程序纯属作孽……

    后记:一般出题目让你实现memcpy,个人理解,其意图至少有以下几点:

    1.写任何程序都能反映出你的代码风格.

    2.考查你是否注意到,要拷贝的源,即const void* src,应该是用const的,避免有意或无意的修改.

    3.指针的类型转化问题,原始参数应该是void *的,你具体操作的时候,应该是转化为某种具体的类型,此处用char比较适合.

    4.注意要判断源src是否和dest重复,如果重复,直接返回或返回错误.

    5.应该还有其他考虑,如果以后想到,再补充.

    补充:后来又重新看了高质量C++/C编程指南,其中,原作者直接对const char *strSrc和strDest进行++操作

    char *strcpy(char *strDest, const char *strSrc);

    {

        assert((strDest!=NULL) && (strSrc !=NULL));   // 2分

        char *address = strDest;                     // 2分

        while( (*strDest++ = * strSrc++) != /0 )     // 2分

           NULL ;

        return address ;                           // 2分

    }

     

     

    展开全文
  • memcpy实现及优化

    2019-03-19 23:01:56
    这是一道面试常考题,要注意的是,函数指针为void类型,注意转换。另一点是两个指针可能有交集,针对这一点,当Dest在Src左边...void* Memcpy(void *Dest, void *Src, unsigned int size){ if(Dest==nullptr||Src==...

    这是一道面试常考题,要注意的是,函数指针为void类型,注意转换。另一点是两个指针可能有交集,针对这一点,当Dest在Src左边时,从低位向高位复制,反之,从高位向低位倒序复制。另外当size大于Dest长度时将报错。

    最简:

    void* Memcpy(void *Dest, void *Src, unsigned int size){
        if(Dest==nullptr||Src==nullptr)
            return nullptr;
        char* tempDest=(char*) Dest;
        char* tempSrc=(char*) Src;
        if(Dest<Src){
            while(size--){
                *(tempDest++)=*(tempSrc++);
            }
        }
        else{
            tempDest+=size-1;
            tempSrc+=size-1;
            while(size--){
                *(tempDest--)=*(tempSrc--);
            }
        }
        return Dest;
    }

    改进:地址对齐时以CPU字长来拷贝,不对齐时按字节拷贝

    void* Memcpy(void *Dest, void *Src, unsigned int size){
        if(Dest==nullptr||Src==nullptr)
            return nullptr;
        int* tempDest=(int*) Dest;
        int* tempSrc=(int*) Src;
        unsigned int newsize=size/4;
        unsigned int slice=size%4;
        if(Dest<Src){
            while(newsize--)
                *(tempDest++)=*(tempSrc++);
            while(slice--)
                *((char*) tempDest++)=*((char*) tempSrc++);
        }
        else{
            tempDest=(int*) ((char*)tempDest+size-4);
            tempSrc=(int*) ((char*)tempSrc+size-4);
            while(newsize--)
                *(tempDest--)=*(tempSrc--);
            while(slice--)
                *((char*) tempDest--)=*((char*) tempSrc--);
        }
        return Dest;
    }

    第二种方法参考:https://www.jianshu.com/p/d474f9a7bce3

    展开全文
  • 动手写代码实现系统函数memcpy功能

    千次阅读 2018-03-02 13:16:05
    memcpy函数可以实现内存之间的字节拷贝(Copies bytes between buffers.)函数原型:void *memcpy( void *dest, const void *src, size_t count );初步的函数实现代码:#include&lt;stdio.h&gt; #include&...

    memcpy函数可以实现内存之间的字节拷贝(Copies bytes between buffers.)

    函数原型:void *memcpy( void *dest, const void *src, size_t count );

    初步的函数实现代码:

    #include<stdio.h>
    #include<string.h>
    
    char*p = "aabbcc";
    
    void* Memcpy(void *dest, const void *src, size_t count)
    {
    	char*p = (char*)dest;
    	char*p1 = (char*)src;
    	while (count--)
    		*p++ = *p1++;
    	return dest;
    }
    
    int main()
    {
    	char s[20] = {0};
    	Memcpy(s, p, strlen(p));
    	/*Memcpy(s + 2, s, strlen(p));*/
    
    	//memcpy(s, p, strlen(p));
    	//memcpy(s + 2, s, strlen(p));
    	return 0;
    }

    看似大功告成,可是这里面有个bug,分别运行下面两句代码:Memcpy(s + 2, s, strlen(p));memcpy(s + 2, s, strlen(p));你会看到我们自己写的函数和系统函数运行后的效果截然不同:

    可以看到字符数组s是不同的,执行我们自己的Memcpy后,s里面是aaaaaaaa,执行系统的memcpy后,s里面的字母是aaaabbcc,显然我们自己的Memcpy还是有问题的,问题就在于源地址和目标地址发生了一定范围内的重叠,造成在从头往后复制的时候造成了自身污染自身的情况,无法得到预期想要的结果。

    解决方案:

    #include<stdio.h>
    #include<string.h>
    
    char*p = "aabbcc";
    
    void* Memcpy(void *dest, const void *src, size_t count)
    {
    	char*p = (char*)dest;
    	char*p1 = (char*)src;
    	//while (count--)
    	//	*p++ = *p1++;
    	while (count--)
    		*(p + count) = *(p1 + count);
    	return dest;
    }
    
    int main()
    {
    	char s[20] = {0};
    	Memcpy(s, p, strlen(p));
    	Memcpy(s + 2, s, strlen(p));
    
    	//memcpy(s, p, strlen(p));
    	//memcpy(s + 2, s, strlen(p));
    	return 0;
    }

    可以看到运行的效果和系统函数的一样了。

    展开全文
  • 实现memcpy函数

    2018-06-21 20:34:09
    十分有趣,因为之前遇到这类系统API都是直接调用的、并没有考虑其中的实现细节,故记录一下:void my_memcpy(void* dst, const void* src, size_t len)//接口通用性 { assert((dst != NULL) &amp;&amp; ...
  • memcpy函数的实现代码

    2012-05-12 13:03:03
    memcpy函数的实现代码,简述了memcpy函数的实现,自己编写memcpy函数
  • c语言实现memcpy

    2021-03-12 14:22:45
    今天到I 公司去面试,面试方式比较特殊,没有笔试,就是2 个面试官,一人一句轮番发问,涉及面很广,涉及到操作系统(MMU 、page out...所有问题都是口头表述,只在纸上写了一个memcpy 程序,用C 语言实现,脑子一发蒙,
  • 关于memcpy实现

    2013-12-12 15:12:23
    今天去面试,面试官出了一个关于memcpy的函数原型的实现的问题,本来这个问题是很简单的,但是不知道当时怎么脑子一抽竟然写错了,真是”累觉不爱”了.感觉这份工作算是泡汤了,算了... memcpy实现内存拷贝,根据这个问...
  • C语言实现memcpy

    千次阅读 2011-07-03 14:51:12
    c语言实现memcpy 今天到I 公司去面试,面试方式比较特殊,没有笔试,就是2 个面试官,一人一句轮番发问,涉及面很广,涉及到操作系统(MMU 、page out 、process/thread 、semaphore 、interrupt), OOP( 多态
  • strcpy以及memcpy实现

    千次阅读 2010-02-09 17:51:00
    上过大学的计算机系的莘莘学子们,... 前面的文章分析了strstr的各种实现,本文分析两个更加普遍的函数,这就是strcpy以及memcpy,strcpy是各大计算机类型考试或者面试中几乎必不可少的考点,国产教科书或者微软官方几
  • 参考地址:... 1:函数原型 void * memcpy ( void * destination, const void * source, size_t num ); 实现1: void *mymemcpy(void *dst,const void *src,si
  • memcpy函数的实现及改进 memcpy主要是用来拷贝不重叠的内存块。下面一步步的来改进memcpy实现。 最初的解决方法是使memcpy对NULL指针进行检查,如果指针为NULL,就给出一条错误信息,并中止memcpy的执行。 #...
  • 关于memcpy()的实现

    千次阅读 2019-03-24 19:42:43
    关于memcpy实现很多同学可能一开始有和我一样的想法,就是将src的内容一个字节一个字节的复制到dest中。这样实现方法未尝不可,但是我们都知道CPU每次取存内存中的数据时,是按照地址总线大小来存取的。以32位的...
  • 本文转载自:strcpy函数实现 大家一般认为名不见经传strcpy函数实现不是很难,流行的strcpy函数写法是:char *my_strcpy(char *dst,const char *src) { assert(dst != NULL); assert(src != NULL); char *ret = ...
  • linux下实现memcpy_s函数

    千次阅读 2018-08-13 16:48:48
    memcpy_s是windows下的一种安全内存操作函数,但是linux下并没有实现,在此自己实现一个类似功能的函数memcpy_st: int memcpy_st(void *det, size_t detSize, const void * src, size_t srcSize, char *cppName, ...
  • 不调用C库函数实现memmove-memcpy函数功能。
  • CPY CPYM CPYP CPYE SET ...在大多数的[操作]系统中,memcpy()、memset()等函数的实现,其实都一个字节一个字节的处理。翻译成汇编后无非就算循环执行ldr、str指令 memcpy的底层实现: _PTR _DEFUN(memcpy, (dst0, src0
  • 闲话不多说,今天来看看汇编中如何实现memcpy和memset(脑子里快速回忆下你最后一次接触汇编是什么时候......) 2 函数是如何被调用的 栈的简单介绍 栈对函数调用来说特别重要,它其实就是进程虚拟地址空间中的一...
  • strcpy 与memcpy 的用法以及C语言实现

    千次阅读 2015-01-28 13:08:11
    size_t是标准c库中定义的,应为unsigned int,在64位系统中应为long unsigned int.该类型保证可以有足够的存储空间,提供给传过来的数据。 void *:void指针可以指向任何类型的数据,即可以用任何类型的数据给void...
  • Strcpy函数1.strcpy声明char * strcpy( char * dest, const char * src );功能:把 src 所指由NULL结束的字符串复制到 dest 所指的数组中。 说明:src 和 dest 所指内存区域不可以重叠且...2. strcpy的实现实现要求:

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,578
精华内容 16,631
关键字:

系统memcpy实现