这三个函数都是内存拷贝,目的都是将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个字节,不会因为遇到字符串结束' '而结束
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、 结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符" "才结束,所以容易溢 出。memcpy则是根据其第3个参数 决定复制的长度。
3 、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
返回值: 返回指向dest的指针
函数实现:
{
assert(dest!=NULL && src != NULL);
char* d=dest;
const char* s=src;
while(n--)
*d++ = *s++;
return 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);
}
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;
}
若不在以上范围内,则源数据会被更改。 如:
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));
或是直接char *p=b+2;memmove(p,b,sizeof(b));
输出数据会发现b中数据输出已被更改。
发现即使a数组指向的空间不够存储数据,也能够移动成功。
发现即使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',' '};
char p[2]={'q','w'};//或char *p=a+2;
memmove(p,a,sizeof(a));
puts(a);
printf("_____________________________________________ ");
puts(p);
printf("_____________________________________________ ");
for(i =0;i<10;i++)
printf("%c %d ",*(a+i),a+i);
printf("_____________________________________________ ");
for(i =0;i<8;i++)
printf("%c %d ",*(p+i),p+i);
return 0;
}
#include<stdlib.h>
#include<string.h>
int main()
{
int i=0;
char a[9]={'a','b','c','d','e','f','g','h',' '};
char p[2]={'q','w'};//或char *p=a+2;
memmove(p,a,sizeof(a));
puts(a);
printf("_____________________________________________ ");
puts(p);
printf("_____________________________________________ ");
for(i =0;i<10;i++)
printf("%c %d ",*(a+i),a+i);
printf("_____________________________________________ ");
for(i =0;i<8;i++)
printf("%c %d ",*(p+i),p+i);
return 0;
}
观察输出结果。
把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。
可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。 如果目的存储空间分配足够的空间,则便不会出现覆盖问题。
把memmove(p,a,sizeof(a));改为memcpy(p,a,sizeof(a));或memccpy(p,a,'e',sizeof(a));再观察输出结果。
可以看出在目的存储空间不足时,便会出现源数据被覆盖改变的问题。 如果目的存储空间分配足够的空间,则便不会出现覆盖问题。
http://blog.csdn.net/q5707802/article/details/27236619