memset 、memmcpy、memmove实现及其区别

来源:互联网 发布:monkey软件 编辑:程序博客网 时间:2024/06/02 23:30

这三个函数实在是太经典了,不得不自己来实现一遍。

三个函数的原型如下:

void* memset(void *des, int val, size_t size) void * memcpy(void *des, const void* src, size_t size)void * memmove(void *des, const void *src, size_t size)

实现如下:

void* memset(void *des, int val, size_t size) {void *start = des;while (size--) {*(char*) des = (char) val;des = (char *) des + 1;//(char*) des++;//des = (char* )des + 1;}return start;}void * memcpy(void *des, const void* src, size_t size) {void *ret = des;while (size--) {*(char *) des = *(char *) src;des = (char *)des + 1;src = (char *)src + 1;//(char *) des++;//(char *) src++;}return ret;}void * memmove(void *des, const void *src, size_t size) {void *ret = des;if (des < src || (char *) des > (char *) src + size - 1) {while (size--) {*(char *) des = *(char *) src;des = (char *) des + 1;src = (char *)src + 1;//(char *) src++;//(chr *) des ++;}}else{des = (char *)des + size - 1;src = (char *)src + size - 1;while (size -- > 0){*(char *) des = *(char *) src;//(char *) des--;//(char *) src--;des = (char *)des - 1;src = (char *)src - 1;}}return ret;}

不采用//中的写法是因为包报出警告:warning: value computed is not used

看起来不爽。

注意事项:

(1)使用memset的时候,要把最后一位或者最后一位的下一位置为‘\0’;

char buffer[20] = "hello";memset(buffer, '1', sizeof(char)*20);printf("%s\n",buffer);运行结果:111111111111111111110@char buffer[20] = "hello";memset(buffer, '1', sizeof(char)*20);buffer[20] = '\0';printf("%s\n",buffer);运行结果:11111111111111111111

因为在prinf一个字符串的时候,printf函数是遇见‘\0就停止。想第一个例子中的,buffer[20]都是‘1’,结束没有‘\0’,所以打印出来的结果就不确定。当然,也有可能是对的,那只是运气好而已。

(2)memcpy和strcpy的区别:

实际上区别只有一个,strcpy的操作对象只能是char *,而memcpy操作的对象是void *。(什么类型的都可以)。实际上,在memcpy的实现上,都是将(void *)装换成为了(char *)来做的,其实跟strcpy一样。

(3)memmove和memcpy的区别:

区别就是memmove要考虑内存区间重叠的情况,而memcpy不会。

关于这个问题,可以用下面的图片来解释:

内存区间重叠的情况如下和不会出现内存区间重叠的情况:


假设des为src + 2,如果按照memcpy处理,从头开始拷贝,就要出现下面的悲剧:


src的内存都被污染了,而且如果这时候打印*des开头的内存,仍然会出现未定义的情况:因为'\0'被覆盖了。

char buffer5[10] = "1234";memcpy(buffer5 + 2, buffer5, sizeof(buffer5));printf("%s\n", buffer5);char buffer6[10] = "1234";memmove(buffer6 + 2, buffer6, sizeof(buffer6));printf("%s\n",buffer6 + 2);
运行结果:
121212121212????"
1234


原创粉丝点击