内存重叠之strcpy&memmove

淘宝面试题:

已知strcpy函数的原型是:

char *strcpy(char *dst, const char *src);

1:实现strcpy函数;

2:解释为什么返回char *;

3: 假如考虑dst和src内存重叠情况,strcpy如何实现;

原始代码:

char *my_strcpy(char *dst,const char *src)
{
	char *ret = dst;
	while(*src != '\0')
	{
		*dst++ = *src++;
	}
	 *dst = '\0';
	 return ret;
}

改进代码:

char *my_strcpy(char *dst,const char *src)//1
{
	assert(dst != NULL && src != NULL);//2
	char *ret = dst;//3
	while((*dst++ = *src++) != '\0');
	return ret;
}
//1:使用const,保证源字符串不被改变
//2:检查指针的有效性,增强代码的健壮性,使用NULL(拼写错误,编译器容易检查出来),而非0,增强程序的可维护性
//3:保存目标字符串的地址,程序结束时返回
//返回char*:使函数能够支持链式表达式:如:int lenth = strlen(strcpy(dst,src));

考虑内存重叠:

char *my_memmove(char *dst,const char *src,size_t lenth)
{
	assert(dst != NULL && src != NULL);
	char *ret = dst;

	if(dst<src || dst>=src+lenth)//正常情况,从低地址往高地址依次拷贝
	{
		while(lenth--)
		{
			*dst++ = *src++;
		}
	}
	else//内存重叠情况,从高地址往低地址拷贝
	{
		dst = dst + lenth - 1;//要存放元素的最后一个位置
		src = src + lenth - 1;//最后一个要拷贝的元素的地址
		while(lenth--)
		{
			*dst-- = *src--;
		}
	}
	return ret;
}

//考虑内存重叠----my_strcpy
char *my_strcpy(char *dst,const char*src)
{
	assert(dst != NULL && src != NULL);
	char *ret = dst;
	my_memmove(dst,src,strlen(src)+1);
	return ret;
}

查看memmove函数原型:

void *my_memmove(void *dst,const void *src,size_t lenth)

实现如下:

void *my_memmove(void *dst,const void *src,size_t lenth)
{
	assert(dst != NULL && src != NULL);

	void *ret = dst;
	char *dst1;//保存目标数组:强制转化类型后的地址
	char *src1;//  保存源数组:强制转化类型后的地址
	
	if((unsigned char *)dst<(unsigned char *)src 
		||(unsigned char *)dst>=((unsigned char *)src+lenth))
	{
		dst1 = (char *)dst;
		src1 = (char *)src;
	
		while(lenth--)
		{
			*dst1++ = *src1++;
		}
	}
	else
	{
		dst1 = (char *)dst + lenth - 1;//问题?????????
		src1 = (char *)src + lenth - 1;
		while(lenth--)
		{
			*dst1-- = *src1--;
		}
	}
	return ret;
}

问题:

dst1 = (char *)dst + lenth - 1;不应该指向最后一个空间之后,再强制类型转化么,如

int a[2]  a+2-1指向最后一个空间,(char*)a+2-1并未指向最后一个空间,可是改成

(char*)(dst + lenth - 1);由于dst类型是void,无法加lenth,,那该怎么解决呢????

希望得到你们的解答,谢谢微笑





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值