9. memcpy() memccpy() memmove() strcpy() memset()
部分参考: 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()的更多相关文章
- memcpy、memmove、memset及strcpy函数实现和理解
memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...
- strcpy()、memcpy()、memmove()、memset()的内部实现
一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...
- memcpy、memmove、memset、memchr、memcmp、strstr详解
第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...
- memcpy、memmove、memset
void * memcpy(void * dst, const void * src, size_t count) { void *res=dst; while (count--) { *(char* ...
- memmove和memcpy 以及strcmp strcpy几个库函数的实现
memmove和memcpy 1.memmove 函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向 ...
- 不使用库函数、自己编写的(strlen、strcpy、strcmp、strcat、memcmp、memcpy、memmove)
不使用库函数.自己编写的(strlen.strcpy.strcmp.strcat.memcmp.memcpy.memmove) //求字符串长度的函数 int my_strlen(const char ...
- memcpy与memmove的区别
在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...
- 关于memcpy和memmove的一点说明
今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...
- C/C++之Memcpy and memmove
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...
随机推荐
- MYSQL 体系结构图
- “too many open files" ----增大打开的文件数
http://www.cnblogs.com/ibook360/archive/2012/05/11/2495405.html [root@localhost ~]# ab -n -c http:/ ...
- JQ插件之imgAreaSelect实现对图片的在线截图功能(java版)
前言:在做网站的时候经常用的功能就是,用户上传图片对自己上传的图片进行截图,DIV自己的头像.或者上传幻灯片大图进行DIV设置小图. 解决方案:目前我知道的解决方案有两个如下: 一.fla ...
- 【CSS中width、height的默认值】
对于初学者来说,CSS中的width.height的默认值是很神奇的,因为经常看到如下这样的代码:明明只给一个#father标签(红色的div)设置了一个width,为啥它在浏览器中显示出来是有一个固 ...
- 关于AuthorizeAttribute使用
在开发中,假如你只对一个角色进行权限处理,你可以这么写 class ActionAuthAttribute : AuthorizeAttribute { private RoleType _roleT ...
- HTML 详细介绍
什么是 HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (ma ...
- 读写Excel
有读Excel,也有生成相同格式的Excel.需要引用Microsoft.Office.Interop.Excel.dll public string ShiPin() { //获取项目下的目录 st ...
- 使用<br>标签分行显示文本
对于上一小节的例子,我们想让那首诗显示得更美观些,如显示下面效果: 怎么可以让每一句诗词后面加入一个折行呢?那就可以用到<br />标签了,在需要加回车换行的地方加入<br /> ...
- Python网页爬虫(一)
很多时候我们想要获得网站的数据,但是网站并没有提供相应的API调用,这时候应该怎么办呢?还有的时候我们需要模拟人的一些行为,例如点击网页上的按钮等,又有什么好的解决方法吗?这些正是python和网页爬 ...
- mysql操作1
一.连接MYSQL.格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root - ...