memset 、memmcpy、memmove实现及其区别

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

三个函数的原型如下:

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


你可能感兴趣的:(buffer)