这三个函数都是内存拷贝,目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。 

      void *memmove(void *dest,void*src,int count)
     void *memcpy(void *dest,void *src,int count)
      void *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'而结束
                  strcpy和memcpy主要有以下3方面的区别。
            1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、                              结构体、类等。
            2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢                               出。memcpy则是根据其第3个参数  决定复制的长度。
            3 、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
        返回值:   返回指向dest的指针
       函数实现:

void* memcpy(void* dest,const void* src, size_t n)

{
   
assert(dest!=NULL && src != NULL);
   
char* d=dest;
  const char* s=src;
                while(n--)
                   *d++ = *s++;
        
return 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)立即停止复制。
     返回值:  如果c没有被复制,则返回NULL,否则,返回dest中字符c 后面紧挨一个字符位置的指针
     函数实现:
void*
memccpy(void* dest,const void* src, int c, size_t n)

{
     assert(dest!=NULL && src != NULL);
     while( n )

{
*(char
*) dest = *(char *)srcl;
dest
= (char *)dest + 1;
if(*(char
*)src == (char)c)
break;
src
= (char *)src + 1;
n--;
}
         return (n ? dest : NULL);
        }
 
       头文件: #include <string.h>
       函数原型: void *memmove(void *dest, const void *src, size_t n);
       函数说明:由src所指内存区域复制count个字节到dest所指内存区域。如果目标区域和源区域有重叠的话,                      memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。memmove能够保证源                串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域                没有重叠则和memcpy函数功能相同。
             memmove的处理措施:
                    (1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
                   (2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
                   (3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
      函数实现:
             void *memmove(void *dest, const void *src, size_t n)
            {
assert(dest!=NULL
&& src != NULL);
char
*d = (char *)dest;
const
char* s = (const char*)src;
if(s
> d)
{
while(n--)
*d++
= *s++;
}
else
if(s < d)
{
d
= d + n - 1;
s
= s + n - 1;
while(n--)
*d--
= *s--;
}
return
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>

int main()
    {
         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); 
    return 0;
     }

 
观察输出结果。  
      把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。  
      可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。  如果目的存储空间分配足够的空间,则便不会出现覆盖问题。 
 
http://blog.csdn.net/q5707802/article/details/27236619

memmove、memccpy和memcpy的更多相关文章

  1. C++中memcpy和memmove

    二者都是内存拷贝 memcpy内存拷贝,没有问题;memmove,内存移动?错,如果这样理解的话,那么这篇文章你就必须要好好看看了,memmove还是内存拷贝.那么既然memcpy和memmove二者 ...

  2. memcpy与memmove

    函数原型: void* memcpy(void *dst,void const *src,size_t count) void* memmove(void *dst,void const *src,s ...

  3. C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理

    ①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...

  4. memmove和memcpy函数的区别及实现

    一.memmove()和memcpy()函数和strcpy()函数的区别: (1)使用的类型不同,strcpy()函数只对字符串进行操作:memmove()和memcpy()函数对所有类型都适用,为内 ...

  5. C语言memcpy()函数和memmove()函数

    C语言memcpy()函数和memmove()函数 关于 memcpy() 函数,请先看链接. memcpy() 函数和 memmove() 函数的函数原型如下: void* memcpy(void ...

  6. 内存及字符串操作篇strlen strchar strcmp strcoll strcpy strdup strstr strtok strspn strrchr bcmp bcopy bzero index memccpy memset

    bcmp(比较内存内容) 相关函数 bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp 表头文件 #include<string.h> 定 ...

  7. memcpy code

    memcpy #include <stddef.h> //#include <stdint.h> //uintptr_t is quoted.#include "st ...

  8. memmove 对同一个指针不操作

    memmove 对同一个指针不操作,所以调用memmove之前不用比较两个指针是否相同 void CTestDLLDlg::OnBnClickedButton6() { ; char* data = ...

  9. C 标准库 - string.h之memmove使用

    memmove Move block of memory Copies the values of num bytes from the location pointed by source to t ...

随机推荐

  1. [机器学习] Coursera ML笔记 - 逻辑回归(Logistic Regression)

    引言 机器学习栏目记录我在学习Machine Learning过程的一些心得笔记,涵盖线性回归.逻辑回归.Softmax回归.神经网络和SVM等等.主要学习资料来自Standford Andrew N ...

  2. Loader之一:基本原理 分类: H1_ANDROID 2013-11-16 10:29 1923人阅读 评论(0) 收藏

    参考APIDEMO及http://developer.android.com/guide/components/loaders.html#app 1.Introduced in Android 3.0 ...

  3. Colder框架硬核更新(Sharding+IOC)

    目录 引言 控制反转 读写分离分库分表 理论基础 设计目标 现状调研 设计思路 实现之过五关斩六将 动态对象 动态模型缓存 数据源移植 查询表达式树深度移植 数据合并算法 事务支持 实际使用 展望未来 ...

  4. Android自定义组件系列【3】——自定义ViewGroup实现侧滑

    有关自定义ViewGroup的文章已经很多了,我为什么写这篇文章,对于初学者或者对自定义组件比较生疏的朋友虽然可以拿来主义的用了,但是要一步一步的实现和了解其中的过程和原理才能真真脱离别人的代码,举一 ...

  5. xv6 gdb

    The "remote" target does not support "run". https://sourceware.org/gdb/onlinedoc ...

  6. 【9107】Hanoi双塔问题(NOIP2007)

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的 ...

  7. 手把手教你完成App支付JAVA后台-支付宝支付JAVA

    接着上一篇博客,我们暂时完成了手机端的部分支付代码,接下来,我们继续写后台的代码. 后台基本需要到以下几个参数,我都将他们写在了properties文件中: 支付宝参数 AliPay.payURL = ...

  8. php课程 4-14 数组如何定义使用

    php课程 4-14  数组如何定义使用 一.总结 1.各种语言键值对取值和赋值赋值表达式左边的特点是什么? 键值对,用于取值和赋值,取值和赋值的左边都是一样的 2.各种语言键值对取值或者赋值的时候如 ...

  9. js进阶 9-12 js如何实现级联菜单 (章节测试)

    js进阶 9-12  js如何实现级联菜单 (章节测试) 一.总结 一句话总结: 1.js如何实现级联菜单 ? 二维数组,以第一级菜单的文本值做键,以对应的二级菜单选项的文本做值 2.用哪个属性可以获 ...

  10. Hudson版本控制 (备注)

    http://www.ttlsa.com/tools/install-hudson-on-linux/