部分参考: 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个字节,不会因为遇到字符串结束' '而结束
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清空)数组。
说明: 返回指向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 > 0) { n--; *(pDst + n) = *(pSrc + n); } } else // 其他情况,都从前往后拷贝 { int i = 0; 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 ++) != '