内存重叠之strcpy&memmove

来源:互联网 发布:最终幻想15剧情 知乎 编辑:程序博客网 时间:2024/05/18 01:58

淘宝面试题:

已知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);//2char *ret = dst;//3while((*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_strcpychar *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,,那该怎么解决呢????

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





2 0
原创粉丝点击