memcpy实现

来源:互联网 发布:演唱会软件 编辑:程序博客网 时间:2024/06/16 07:49

本文引出memcpy的问题,并提供一个实现方式。
参考了[【C/C++】实现memcpy函数]

问题

首先来看memcpy的定义:

void *memcpy(void *dest, const void *src, size_t n);//If copying takes place between objects that overlap, the behavior is undefined.

对于内存重叠,比如src在dst之前的情形,此时src还没有完成复制,但是已经和dst重合,从而src前面的值将后面的值覆盖,那么后面的值无法再进行对dest进行复制。

考虑如下代码,buf+3与buf内存覆盖,所以输出行为无法预测。总之不能输出正确的结果。
当然,可以用memmove实现,后者是引入了一个临时数组暂时存储src的值,从而可以完成复制。

/c#include <stdio.h>#include <string.h>#define LEN 128int main( void ){    char buf[LEN] = "hello,world!";    char* ret = memcpy( buf+3, buf, strlen(buf) );    ret[strlen(buf)] = 0;    printf( "%s\n", ret );    /*    char* ret = memmove( buf+3, buf, strlen(buf) );    ret[strlen(buf)] = 0;    printf( "%s\n", ret );    */    return 0;}

下面给出一种实现,当内存重叠的时候,需要从后向前复制。

void* Memcpy( void* dest, void* src, size_t n ){    char* psrc = (char*)src; // 此处必须强转,否则通用指针并不关联类型,++操作以及psrc+n操作无法实现。    char* pdst = (char*)dest;    if( !dest || !src ){        return NULL;    }    if( ( psrc < pdst ) && ( psrc + n > pdst) ){ // 从后向前拷贝        psrc = psrc + n - 1;        pdst = pdst + n - 1;        while( n-- ) *pdst-- = *psrc--;    }    else{// 从前向后拷贝        while( n-- ) *pdst++ = *psrc++;    }    return dest;}

补充

早上再次复习了memcpy,有新的收获在此补充!。
1. memcpy是 copy of block,它的本质是内存拷贝。它可以适用于字符串的拷贝,但是并不是仅仅适用于字符串,int[], 或者其它类型都是适用的。具体拷贝的时候,按照字节进行拷贝,但是也可以按照CPU字长进行拷贝。
2. 不是遇见’\0’结束,而是必须拷贝num字节。这是主要是与strcpy的区别。
3. 需要以下两个注意:

  • overlap的问题
  • 溢出的问题,必须保证拷贝的字节数n不超过src以及dest的大小。这一点在程序中是没有办法保证的。因为对于strcpy来说,它可以计算strlen,但是像int[]数组,没法计算。所以,这点需要认为保证。
原创粉丝点击