面试笔试之memcpy函数

void *memcpy(void *dst, void *src, int n)
  1. 首先该函数是可以复制任意类型的空间的,所以参数是void *
  2. 再次,源空间src是不可改变的,应该为const void *,但是在考虑重叠的情况下源空间内容是可能被改变的。
  3. 第三个参数决定了复制的长度
  4. 要考虑源地址、目的地址、n的有效性
  5. 要考虑源地址和目的地址重叠的情况,但是重叠的定义又是什么?原则是什么?
  6. 重叠的情况下如何拷贝?不重叠的情况下又如何拷贝?
  7. 最后返回dst,不要手贱加上'\0'
重叠:
      如果src < dst && src + n > dst,则重叠,要从尾到头拷贝。
     如果src < dst && src + n < dst,则不重叠,要从头到尾拷贝。
     如果src > dst ,则不重叠!还是可以从头到尾拷贝。
原则:
      拷贝之后,不管重叠与否,dst的前n个空间的内容一定是原来src的前n个空间的内容!即使src一定被改变。

Something else:
    1. memcpy未考虑重叠的问题,所以对于重叠是未定义的。。。
    2. memmove考虑了重叠的问题,所以效率比较低。
代码:
 
#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;

// without consideration  of overlap
void * mymemcpy1(void *dst, void *src, int n){
	assert(dst != NULL && src != NULL && n > 0);
	char *pdst = (char *)dst;
	char *psrc = (char *)src;
	while(n--){
		*pdst++ = *psrc++;
	}
	return dst;
}

// 就是要保证复制后,dst的开始n个内容是src的内容
// with consideration  of overlap
void * mymemcpy2(void *dst, void *src, int n){
	assert(dst != NULL && src != NULL && n > 0);
	char *pdst = (char *)dst;
	char *psrc = (char *)src;

	// overlap, copy from end to start, 重叠,从后往前拷贝
	if(psrc < pdst && psrc + n > pdst){
		pdst += n - 1;
		psrc += n - 1;
		while(n--){
			*pdst-- = *psrc--;
		}
	}else{
		// no overlap, copy from start to end
		while(n--){
			*pdst++ = *psrc++;
		}
	}
	return dst;
}

int main(){
	char dst1[20] = "abcdefghijk";
	char dst2[20] = "abcdefghijk";
	cout << "source: " << dst1 << endl;
	mymemcpy1(dst1+2, dst1, 5);
	cout << "mymemcpy1(no overlap): " << dst1+2 << endl;
	mymemcpy2(dst2+2, dst2, 5);
	cout << "mymemcpy2(no overlap): " << dst2+2 << endl;
	return 0;
}

输出:
source: abcdefghijk
mymemcpy1(no overlap): ababahijk
mymemcpy2(no overlap): abcdehijk


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值