C语言面试题:内存拷贝函数

最近,准备找工作,当然是每天刷一些笔试题,看看各个知识点,反正也没有固定的复习线路,就根据自己刷到的题做知识的延申和拓展。
今天看到了一道这样的题:写一个内存拷贝函数
。。。。。。
起先看到这道题的时候感觉自己是不是没学过这门课,看到这道题的时候是什么也不知道,知识点也学的太薄弱了,然后就是熟悉的搜题环节,自己不会的就去网上找呗,反正现在的网络上这么多大佬,不看白不看,看了,理解了,能写出来的,就是自己的东西了。
那么,什么是内存拷贝函数呢?内存拷贝函数写出来是用来做什么的呢?
C语言中提供了一个内存拷贝函数memcpy():

void *memcpy(void *dest,void *src,unsigned int  size);
dest:	目标内存首地址
src:	源内存首地址
size:	需要拷贝字节数
返回值:源内存首地址或NULL

首先,先来引入另一个函数,字符串拷贝函数,strcpy()
strcpy()是用来拷贝字符串的(也只能用来拷贝字符串),以’\0’结束,而内存拷贝函数memcpy()是需要指定拷贝字节数的,各种类型都可以拷贝。
这里需要注意,memcpy()在拷贝的时候是一个字节一个字节的进行搬运的,当目标内存首地址与源内存首地址之间的间距不足以放下需要拷贝的字节数时,就会发生内存重叠的问题,会导致我们拷贝过去的数据把原有的数据覆盖掉了,导致后面的数据出错。
假设一个内存拷贝函数如下:

void *mymemcpy(void *dest,const void *src, int count){
	assert(dest != NULL && src != NULL);
	void *ret = dest;
	while(count--){
		*(char *)dest = *(char *)src;
		dest = (char*)dest+1;
		src = (char *)src+1;
	}
	return ret;
}

这就是一个简单的内存拷贝函数,在这种情况下是不会出错的:

mymemcpy(p,p+1,4);//从高地址向低地址拷贝数据的时候就不会出现内存重叠
mymemcpy(p2,p1,4);//在两个不同的数组空间也不会发生这样的问题
mymemcpy(p+5,p,4);//两个地址相隔的距离足够大,也不会发生问题

mymemcpy(p+1,p,4);//这样就出现问题了,会发现拷贝的全是一个字符

如何解决这个问题呢,其实已经可以找到方法了,做条件判断,

if(src >= dest || (char*)dest >= (char*)src+count)

当会发生内存重叠这个情况时就从高地址开始拷贝,也就是从需要拷贝的最后一个字节来进行拷贝;
所以,一个完整的内存拷贝函数应该如下:

void *mymemcpy(void *dest,const void *src, int count){
	assert(dest != NULL && src != NULL);
	void *ret = dest;
	if(src >= dest || (char *)dest >= (char *)src+count){
		while(count--){
			*(char*)dest=*(char*)src;
			dest = (char*)dest+1;
			src = (char*)src+1;
		}else{
			dest = (char*)dest+count;
			src = (char*)dest+count;
			while(count--){
				dest = (char*)dest-1;
				src = (char*src)-1;
				*(char*)dest = *(char*)src;
			}
		}
	}
	return 0;
}

好了,这就是一个比较完整的内存拷贝函数了,解决了在拷贝过程中可能存在的内存拷贝问题,这个在笔试面试的过程中考的概率还是很大的,还是就是关于字符串的那几个函数,在笔试中经常会遇到的,多去看,多去练,还是什么是解决不了的呢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值