这三个函数实在是太经典了,不得不自己来实现一遍。
三个函数的原型如下:
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