SavorCoding

C/C++ Prime学习要点1——实现memcpy库函数

分类:C/C++

实现一个Memcpy函数。

Memcpy函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);

拷贝多少个?有一个size变量控制拷贝的字节数。函数原型:void *memcpy(void *dest, void *src, unsigned int count);用法:(1)可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等,但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节。

一开始我们很可能写出如下错误代码:

void memcpy(void *dest, void *src, int len){void *p = dest;void *q = src;if( dest == NULL ||src == NULL){return;}for (int i=0; i<len; i++){*p++ = *q++;}}

上面错误代码原因:

考虑内存重叠情况:

1、若没有内存重叠,则从低地址往高地址复制

2、若有内存重叠,则从高地址往低地址复制

代码如下:(这其实也是memmove代码)

void *memcpy(void *dst, const void *src, size_t len){ if(NULL == dst || NULL == src){ return NULL; }void *ret = dst;if(dst <= src || (char *)dst >= (char *)src + len){ //没有内存重叠,从低地址开始复制 while(len–){ *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } }else{ //有内存重叠,从高地址开始复制 src = (char *)src + len – 1; dst = (char *)dst + len – 1; while(len–){ *(char *)dst = *(char *)src; dst = (char *)dst – 1; src = (char *)src – 1; } } return ret;}memcpy 与 memmove区别:

memcpy和memmove()都是C语言中的库函数,在头文件string.h中,,作用是拷贝一定长度的内存的内容,原型分别如下:void *memcpy(void *dst, const void *src, size_t count);void *memmove(void *dst, const void *src, size_t count);作用是一样的,唯一的区别是,当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。

情况一,拷贝重叠的区域不会出现问题,内容均可以正确的被拷贝。情况二,问题出现在右边的两个字节,这两个字节的原来的内容首先就被覆盖了,而且没有保存。所以接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。实际上,memcpy只是memmove的一个子集。

memcpy没有考虑内存重叠的实现方法:

void *memcpy(void *dest, const void *src, unsigned int count){ assert((dest != NULL) && (src != NULL)); void *address = dest; while (count –){ *(char *) dest = *(char *) src; dest = (char *) dest + 1; src = (char *) src + 1;} return address;}

上一篇面试题38_数字在排序数组中出现的次数

顶0踩0

自己打败自己是最可悲的失败,

SavorCoding

相关文章:

你感兴趣的文章:

标签云: