【C】模拟实现mem系列和str系列函数

  • mem系列函数都是以字节长度进行操作的,因此有时候会造成意想不到的错误
    • 例如:memcpy 在涉及资源管理时的浅拷贝,根本原因是memcpy拷贝了指针的指向,而我们预期是拷贝指针所指的空间内容,string中的拷贝构造。
    • 例如:memset 在给以字节为单位长度的数组设置内容时没问题,但是如果int arr[10]; memset(arr, 1, sizeof(arr));数组每个元素都被赋值为 16843009,二进制为 0000 0001 0000 0001 0000 0001 0000 0001,意味着给每个字节赋值 0000 0001,造成错误。
    • memset,在对拥有虚表的对象初始化时,memset(&B, 0, sizeof(B));,会将对象模型中前4字节指针的值全部清空,造成错误

memcpy函数原型:
void* memcpy(void* _Dst, const void* _Src, size_t _Size);

void* Memcpy(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	assert(dst);
	assert(src);
	while (count--)
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return ret;
}

memset函数原型
void* memset(void* _Dst, int _Val, size_t _Size);

void* Memset(void* dst, int ch, size_t count)
{
	assert(dst);
	void* ret = dst;
	while (count--)
	{
		*(char*)dst = (char)ch;
		dst = (char*)dst + 1;
	}
	return ret;
}

memmove函数原型
void* memmove(void* _Dst, const void* _Src, size_t _Size);

void* Memmove(void* dst, const void* src, size_t count)
{
	void* ret = dst;
	// 如果字符从前开始拷贝不会产生问题,则效果和memcpy相同
	if (dst <= src || (char*)dst >= (char*)src + count)
	{
		while (count--)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst + 1;
			src = (char*)src + 1;
		}			
	}
	// 从后往前开始拷贝
	else
	{
		dst = (char*)dst + count - 1;
		src = (char*)src + count - 1;
		while (count--)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst - 1;
			src = (char*)src - 1;
		}
	}
	return ret;
}

strcpy函数原型
char* strcpy(char* Dst, const char* Src);

char* Strcpy(char* dst, const char* src)
{
	assert(dst);
	assert(src);
	char* ret = dst;
	while (*dst++ = *src++)
	{
		;
	}
	return ret;
}

strlen函数原型
size_t strlen(const char* str);

size_t Strlen(const char* s)
{
	char* p = (char*)s;
	while (*p != '\0')
		++p;
	return p - s;
}
上一篇:opencv常用基础操作


下一篇:Linux下rsync使用方法