memmove、memcpy和memccpy三个函数都是内存的拷贝,从一个缓冲区拷贝到另一个缓冲区。

memmove(void *dest,void*src,int count)

memcpy(void *dest,void *src,int count)

memccpy(void*dest,void*src,int ch,int count)

表头文件: #include <string.h>

定义函数: void *memcpy(void *dest, const void *src, size_t n)

函数说明: memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束

返回值:   返回指向dest的指针

表头文件: #include <string.h>

定义函数: void *memccpy(void *dest, const void *src, int c, size_t n);

函数说明: memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是,memccpy()如果在src中遇到某个特定值(int c)立即停止复制。

返回值:   返回指向dest中值为c的下一个字节指针。返回值为0表示在src所指内存前n个字节中没有值为c的字节。

表头文件: #include <string.h>

定义函数: void *memmove(void *dest, const void *src, size_t n);

函数说明:memmove()是从一个缓冲区移动到另一个缓冲区中。 

返回值:   返回指向dest指针。

当dest <= src-count 或dest >= src+count时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。

若不在以上范围内,则源数据会被更改。

如:

char a[]={'a','b'};

char b[]={'c','d','e','f','g','h'};

memmove(a,b,sizeof(b));

或是直接char *p=b+2;memmove(p,b,sizeof(b));

输出数据会发现b中数据输出已被更改。

发现即使a数组指向的空间不够存储数据,也能够移动成功。

原因|dest - src |<count

如果在使用这些函数时,分配给足够的空间,然后再使用就不会出现覆盖问题。也就是说如果外部分配给的空间不足以存储要拷贝的数据时,就有可能出现源数据被覆盖更改的问题。

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
void main(void)
{
int i=0;
char a[9]={'a','b','c','d','e','f','g','h','\0'};
char p[2]={'q','w'};//或char *p=a+2;
memmove(p,a,sizeof(a));
puts(a);
printf("_____________________________________________\n");
puts(p);
printf("_____________________________________________\n");
for(i =0;i<10;i++)
printf("%c %d \n",*(a+i),a+i);
printf("_____________________________________________\n");
for(i =0;i<8;i++)
printf("%c %d \n",*(p+i),p+i);
}


观察输出结果。

把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。

可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。

如果目的存储空间分配足够的空间,则便不会出现覆盖问题。

 

strcpy()、memcpy()、memmove()、memset()的实现

strcpy(), 字符串拷贝.

  2strcpy()、memcpy()、memmove()、memset()的实现_i++char *strcpy(char *strDest, const char *strSrc)

  3strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

  4strcpy()、memcpy()、memmove()、memset()的实现_数据_05    assert((strDest!=NULL) && (strSrc !=NULL));

  5strcpy()、memcpy()、memmove()、memset()的实现_数据_05    char *address = strDest;     

  6strcpy()、memcpy()、memmove()、memset()的实现_数据_05    while( (*strDest++ = * strSrc++) != '\0') 

  7strcpy()、memcpy()、memmove()、memset()的实现_数据_05       NULL ; 

  8strcpy()、memcpy()、memmove()、memset()的实现_数据_05    return address ;       

  9strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

 10strcpy()、memcpy()、memmove()、memset()的实现_i++

 11strcpy()、memcpy()、memmove()、memset()的实现_i++memcpy, 拷贝不重叠的内存块 

 12strcpy()、memcpy()、memmove()、memset()的实现_i++void *memcpy(void* pvTo, void* pvFrom, size_t size) //byte是java里的变量类型

 13strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 14strcpy()、memcpy()、memmove()、memset()的实现_数据_05assert(pvTo != NULL && pvFrom != NULL);

 15strcpy()、memcpy()、memmove()、memset()的实现_数据_05void* pbTo = (byte*)pvTo;

 16strcpy()、memcpy()、memmove()、memset()的实现_数据_05void* pbFrom = (byte*)pvFrom;

 17strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21/**//* 内存块重叠吗?如果重叠,就使用memmove */

 18strcpy()、memcpy()、memmove()、memset()的实现_数据_05assert(pbTo>=pbFrom+size || pbFrom>=pbTo+size);

 19strcpy()、memcpy()、memmove()、memset()的实现_数据_05while(size-->0)

 20strcpy()、memcpy()、memmove()、memset()的实现_数据_05    *pbTo++ == *pbFrom++;

 21strcpy()、memcpy()、memmove()、memset()的实现_数据_05return pvTo;

 22strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

 23strcpy()、memcpy()、memmove()、memset()的实现_i++

 24strcpy()、memcpy()、memmove()、memset()的实现_i++void *MemCopy(void *dest,const void *src,size_t count)

 25strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 26strcpy()、memcpy()、memmove()、memset()的实现_数据_05    char *pDest=static_cast<char *>(dest);

 27strcpy()、memcpy()、memmove()、memset()的实现_数据_05    const char *pSrc=static_cast<const char *>(src);

 28strcpy()、memcpy()、memmove()、memset()的实现_数据_05    if( pDest>pSrc && pDest<pSrc+count )

 29strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21    strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 30strcpy()、memcpy()、memmove()、memset()的实现_数据_05        for(size_t i=count-1; i<=0; ++i)

 31strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21        strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 32strcpy()、memcpy()、memmove()、memset()的实现_数据_05            pDest[i]=pSrc[i];

 33strcpy()、memcpy()、memmove()、memset()的实现_i++_43        }

 34strcpy()、memcpy()、memmove()、memset()的实现_i++_43    }

 35strcpy()、memcpy()、memmove()、memset()的实现_数据_05    else

 36strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21    strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 37strcpy()、memcpy()、memmove()、memset()的实现_数据_05        for(size_t i=0; i<count; ++i)

 38strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21        strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 39strcpy()、memcpy()、memmove()、memset()的实现_数据_05             pDest[i]=pSrc[i];

 40strcpy()、memcpy()、memmove()、memset()的实现_i++_43        }

 41strcpy()、memcpy()、memmove()、memset()的实现_i++_43    }

 42strcpy()、memcpy()、memmove()、memset()的实现_数据_05    return pDest;

 43strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

 44strcpy()、memcpy()、memmove()、memset()的实现_i++

 45strcpy()、memcpy()、memmove()、memset()的实现_i++void *Memmove(void *Dst, const void*Src,size_t count)

 46strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 47strcpy()、memcpy()、memmove()、memset()的实现_数据_05assert(Dst && Src);

 48strcpy()、memcpy()、memmove()、memset()的实现_数据_05void* pDst = Dst;

 49strcpy()、memcpy()、memmove()、memset()的实现_数据_05if (Dst<Src && (char*)Dst > (char*)Src + count)

 50strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 51strcpy()、memcpy()、memmove()、memset()的实现_数据_05while(count--)

 52strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 53strcpy()、memcpy()、memmove()、memset()的实现_数据_05   *(char*)Dst = *(char*)Src;

 54strcpy()、memcpy()、memmove()、memset()的实现_数据_05   Dst = (char*)Dst + 1;

 55strcpy()、memcpy()、memmove()、memset()的实现_数据_05   Src = (char*)Src + 1;

 56strcpy()、memcpy()、memmove()、memset()的实现_i++_43}

 57strcpy()、memcpy()、memmove()、memset()的实现_i++_43}

 58strcpy()、memcpy()、memmove()、memset()的实现_数据_05else

 59strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 60strcpy()、memcpy()、memmove()、memset()的实现_数据_05   Dst = (char*)Dst + count - 1;

 61strcpy()、memcpy()、memmove()、memset()的实现_数据_05   Src = (char*)Src + count - 1;

 62strcpy()、memcpy()、memmove()、memset()的实现_数据_05   while(count--)

 63strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21   strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

 64strcpy()、memcpy()、memmove()、memset()的实现_数据_05      *(char*)Dst = *(char*)Src;

 65strcpy()、memcpy()、memmove()、memset()的实现_数据_05      Dst = (char*)Dst -1 ;

 66strcpy()、memcpy()、memmove()、memset()的实现_数据_05      Src = (char*)Src -1 ;

 67strcpy()、memcpy()、memmove()、memset()的实现_i++_43   }

 68strcpy()、memcpy()、memmove()、memset()的实现_i++_43}

 69strcpy()、memcpy()、memmove()、memset()的实现_数据_05return pDst;

 70strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

 71strcpy()、memcpy()、memmove()、memset()的实现_i++

 72strcpy()、memcpy()、memmove()、memset()的实现_i++

 73strcpy()、memcpy()、memmove()、memset()的实现_i++void* memmove(void *dest, const void *src,size_t n) 

 74strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04

 75strcpy()、memcpy()、memmove()、memset()的实现_数据_05    if (n == 0) return 0; 

 76strcpy()、memcpy()、memmove()、memset()的实现_数据_05    if (dest == NULL) return 0; 

 77strcpy()、memcpy()、memmove()、memset()的实现_数据_05    if (src == NULL)    return 0; 

 78strcpy()、memcpy()、memmove()、memset()的实现_数据_05    char *psrc = (char*)src; 

 79strcpy()、memcpy()、memmove()、memset()的实现_数据_05    char *pdest = (char*)dest; 

 80strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21    if((dest <= psrc) || (pdest >= psrc + n)) /**//*检查是否有重叠问题 */ 

 81strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21        strcpy()、memcpy()、memmove()、memset()的实现_数据_04

 82strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21         for(int i=0; i < n; i++) /**//*正向拷贝*/ 

 83strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21          strcpy()、memcpy()、memmove()、memset()的实现_数据_04

 84strcpy()、memcpy()、memmove()、memset()的实现_数据_05           *pdest = *psrc; 

 85strcpy()、memcpy()、memmove()、memset()的实现_数据_05           psrc++; 

 86strcpy()、memcpy()、memmove()、memset()的实现_数据_05           pdest++; 

 87strcpy()、memcpy()、memmove()、memset()的实现_i++_43          } 

 88strcpy()、memcpy()、memmove()、memset()的实现_i++_43        } 

 89strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21        else /**//*反向拷贝*/ 

 90strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21        strcpy()、memcpy()、memmove()、memset()的实现_数据_04

 91strcpy()、memcpy()、memmove()、memset()的实现_数据_05          psrc += n; 

 92strcpy()、memcpy()、memmove()、memset()的实现_数据_05          pdest += n; 

 93strcpy()、memcpy()、memmove()、memset()的实现_数据_05          for(int i=0;i<n;i++) 

 94strcpy()、memcpy()、memmove()、memset()的实现_头文件_20strcpy()、memcpy()、memmove()、memset()的实现_数据_21           strcpy()、memcpy()、memmove()、memset()的实现_数据_04

 95strcpy()、memcpy()、memmove()、memset()的实现_数据_05            psrc--; 

 96strcpy()、memcpy()、memmove()、memset()的实现_数据_05            pdest--; 

 97strcpy()、memcpy()、memmove()、memset()的实现_数据_05            *pdest = *psrc; 

 98strcpy()、memcpy()、memmove()、memset()的实现_i++_43           } 

 99strcpy()、memcpy()、memmove()、memset()的实现_i++_43        } 

100strcpy()、memcpy()、memmove()、memset()的实现_数据_05   return dest;

101strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

102strcpy()、memcpy()、memmove()、memset()的实现_i++

103strcpy()、memcpy()、memmove()、memset()的实现_i++memset:把buffer所指内存区域的前count个字节设置成字符c

104strcpy()、memcpy()、memmove()、memset()的实现_i++

105strcpy()、memcpy()、memmove()、memset()的实现_i++void * Memset(void* buffer, int c, int count)

106strcpy()、memcpy()、memmove()、memset()的实现_c++_02strcpy()、memcpy()、memmove()、memset()的实现_数据_03strcpy()、memcpy()、memmove()、memset()的实现_数据_04{

107strcpy()、memcpy()、memmove()、memset()的实现_数据_05char* pvTo=(char*)buffer;

108strcpy()、memcpy()、memmove()、memset()的实现_数据_05assert(buffer != NULL);

109strcpy()、memcpy()、memmove()、memset()的实现_数据_05while(count-->0)

110strcpy()、memcpy()、memmove()、memset()的实现_数据_05*pvTo++=(char)c;

111strcpy()、memcpy()、memmove()、memset()的实现_数据_05return buffer;

112strcpy()、memcpy()、memmove()、memset()的实现_头文件_10}

113strcpy()、memcpy()、memmove()、memset()的实现_i++