天天看點

模拟實作memcpy,memmove,memsetmemcpymemmovememset

memcpy

c和c++使用的記憶體拷貝函數,memcpy函數的功能是從源src所指的記憶體位址的起始位置開始拷貝n個位元組到目标dest所指的記憶體位址的起始位置中。

函數原型為:

void *memcpy(void *dest, const void *src, size_t n);
           

模拟實作:

void* my_memcpy(void* dest, const void* src, size_t n)
{
	assert(dest);
	assert(src);
	char* pdest = (char*)dest;
	const char* psrc = (const char*)src;
	while (n--)
	{
		*pdest++ = *psrc++;
	}
	return dest;
}
           

注意:source和destin所指的記憶體區域可能重疊,但是如果source和destin所指的記憶體區域重疊,那麼這個函數并不能夠確定source所在重疊區域在拷貝之前不被覆寫。而使用memmove可以用來處理重疊區域。函數傳回指向destin的指針。

memmove

memmove用于從src拷貝count個位元組到dest,如果目标區域和源區域有重疊的話,memmove能夠保證源串在被覆寫之前将重疊區域的位元組拷貝到目标區域中。但複制後src内容會被更改。但是當目标區域與源區域沒有重疊則和memcpy函數功能相同。

模拟實作:

void* my_memmove(void* dest, const void* src, size_t count)
{
	assert(dest);
	assert(src);
	char* pdest = (char*)dest;
	const char* psrc = (const char*) src;

	if (pdest <= psrc || psrc + count <= pdest)//正常情況下,從前往後拷貝
	{
		while (count--)
			*pdest++ = *psrc++;
	}
	else
	{
		while (count--)
			*(pdest + count) = *(psrc + count);
	}

	return dest;
}
           

測試用例:

void Test_Memmove()
{
	char arr[10] = "abcdefg";
	char arr0[10] = "abcdefg";
	char arr1[10] = { 0 };
	my_memmove(arr + 2, arr, 4);
	my_memmove(arr1, arr0, 4);
	printf("記憶體覆寫情況:%s\n", arr + 2);
	printf("正常情況:%s\n", arr1);
}
void Test_Memcpy()
{
	char arr[10] = "abcdefg";
	char arr0[10] = "abcdefg";
	char arr1[10] = { 0 };
	my_memcpy(arr + 2, arr, 4);
	my_memcpy(arr1, arr0, 4);
	printf("記憶體覆寫情況:%s\n", arr+2);
	printf("正常情況:%s\n", arr1);
}
           

memset

函數原型:

void *memset( void *dest, int c, size_t count );
           

函數功能:将dest中目前位置後面的count個位元組,用 c 替換并傳回 dest 。

模拟實作:

void* my_memset(void *dest, int c, size_t count)
{
	assert(dest);
	char* tmp = (char*)dest;
	while (count--)
	{
		*tmp = (char)c;
		tmp++;
	}
	return dest;
}
           

繼續閱讀