部分参考: http://www.cppblog.com/kang/archive/2009/04/05/78984.html

表头文件: #include <string.h>
定义函数: void *memcpy(void *dest, const void *src, size_t n)
函数说明: memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束

strcpy()只能用于字符串的copy,而memcpy()可用于任意类型,包括数组、结果体、对象(硬拷贝);此外,memcpy被编译优化为MOVSB, MOVSW等的机器码内存块

搬动,有的例程上说 memcpy实现是用int类型,每次拷贝4个字节。strcpy是单个字节拷贝的。

返回值:   返回指向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()是从一个缓冲区移动到另一个缓冲区中。 该函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销。性能较memcpy低。
返回值:   返回指向dest指针。

当 dest <= src-count  或 dest >= src+count 时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。
若不在以上范围内,则源数据会被更改。此时,memcpy(), memccpy()的行为是未定义的(有的库考虑了重叠,有的没有考虑,vs貌似考虑了),只能使用更为安全但性能较低的memmove().

如:
char a[]={'a','b'};
char b[]={'c','d','e','f','g','h'};
memmove(a,b,sizeof(b));

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

若:

char *p=b+2;

memmove(p,b,sizeof(b));

输出数据会发现b中数据输出已被更改。
原因|dest - src |<count,出现覆盖问题。也就是说如果外部分配给的空间不足以存储要拷贝的数据时,就有可能出现源数据被覆盖更改的问题。

如果在使用这些函数时,分配给足够的空间,然后再使用就不会出现覆盖问题。

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

定义函数:   extern void *memset(void *buffer, int c, int count);
  功能: 把buffer所指内存区域的前count个字节设置成字符 c。如' ' , '\0' 。通常用来赋值字符数组 及 清空各类型(用0清空)数组。

说明: 返回指向buffer的指针。

对于int数组,有:

int a[5];

使用

memset(a, 0, sizeof(int)*5); // 可以用0来清空数组a,a中各元素值为 00000000 00000000 00000000 00000000,即 0.

memset(a, 1, sizeof(int)*5);

原本想要给a赋值1, 结果会给每个int(4个字节)的每个字节赋值为00000001, 结果每个int值为 00000001 00000001 00000001 00000001,即 16843009,而不是1了。

自定义这些函数:

考虑内存重叠的 memcpy 

void* Memcpy(void* dst , const void* src, size_t n)
{
if (dst == NULL || src == NULL)
{
return NULL;
}
char* pDst = static_cast<char*>(dst); // (char*)dst;
char* pSrc = const_cast<char*>(static_cast<const char*>(src)); // (char*)src;
if (pDst > pSrc && (pSrc + n) > pDst) // 只有当dst 在 src 之后,且 (src + n) > dst时, 会将之前copy的内容覆盖掉,故此时因自后向前拷贝
{
while (n > )
{
n--;
*(pDst + n) = *(pSrc + n);
}
}
else // 其他情况,都从前往后拷贝
{
int i = ;
while (i < n)
{
*(pDst + i) = *(pSrc + i);
i++;
}
}
return dst;
}

strcpy

char* Strcpy(char* dst, const char* src)
{
if (dst == NULL || src == NULL)
{
return NULL;
}
while ( (*dst++ = *src ++) != '\0'); // 先取值,再++
return dst;
}

9. memcpy() memccpy() memmove() strcpy() memset()的更多相关文章

  1. memcpy、memmove、memset及strcpy函数实现和理解

    memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...

  2. strcpy()、memcpy()、memmove()、memset()的内部实现

    一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...

  3. memcpy、memmove、memset、memchr、memcmp、strstr详解

    第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...

  4. memcpy、memmove、memset

    void * memcpy(void * dst, const void * src, size_t count) { void *res=dst; while (count--) { *(char* ...

  5. memmove和memcpy 以及strcmp strcpy几个库函数的实现

    memmove和memcpy 1.memmove 函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向 ...

  6. 不使用库函数、自己编写的(strlen、strcpy、strcmp、strcat、memcmp、memcpy、memmove)

    不使用库函数.自己编写的(strlen.strcpy.strcmp.strcat.memcmp.memcpy.memmove) //求字符串长度的函数 int my_strlen(const char ...

  7. memcpy与memmove的区别

    在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...

  8. 关于memcpy和memmove的一点说明

    今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...

  9. C/C++之Memcpy and memmove

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...

随机推荐

  1. diy 电脑 重装系统

    1\组装好电脑 2\硬盘的红灯只亮一会,找不到 硬盘 .bios里 硬盘设置里 IDE修改为 ACHI即可. 3\老毛桃 \ 用桌面的那个分区软件 分区 100G,300G 4\找到U盘 的iso 文 ...

  2. [转] 用SBT编译Spark的WordCount程序

    问题导读: 1.什么是sbt? 2.sbt项目环境如何建立? 3.如何使用sbt编译打包scala? [sbt介绍 sbt是一个代码编译工具,是scala界的mvn,可以编译scala,java等,需 ...

  3. [转] __thread关键字

    http://blog.csdn.net/liuxuejiang158blog/article/details/14100897 __thread是GCC内置的线程局部存储设施,存取效率可以和全局变量 ...

  4. linux服务器上的php代码通过nginx发布,解决pathinfo模式问题

    附件1为修改前的正常访问php配置文件      附件2为修改后的能通过url地址访问php项目的配置文件    具体操作网址 如下:www.itokit.com/2012/0308/73275.ht ...

  5. Android之发送短信的两种方式

    SMS涉及的主要类SmsManager 实现SMS主要用到SmsManager类,该类继承自java.lang.Object类,下面我们介绍一下该类的主要成员. 公有方法: ArrayList< ...

  6. Android(java)学习笔记241:多媒体之 MediaPlayer使用

    MediaPlayer类可用于控制音频/视频文件或流的播放.关于如何使用这个类的方法还可以阅读VideoView类的文档. 1.MediaPlayer 状态图       对播放音频/视频文件和流的控 ...

  7. 自签名SSL生成

    本教程以AppServ生成自签名证书为例,同时配置OpenSSL环境1.生成自签名证书,控制台程序进入Apache目录下的bin目录 >openssl req -config ../conf/o ...

  8. Linq101-Element

    using System; using System.Collections.Generic; using System.Linq; namespace Linq101 { class Element ...

  9. Cacti添加threshold、monitor和setting

    Cacti版本:Version 0.8.8b 一.插件介绍: monitor:通过简单明了的图标提供服务器的运行状态 settings:给不同的插件提供一些共用的信息,如邮件信息,dns信息thold ...

  10. javascript基础学习(十二)

    javascript之BOM 学习要点: 屏幕对象 History对象 Location对象 一.屏幕对象 Screen对象是一个由javascript自动创建的对象,该对象的主要作用是描述客户端的显 ...