Dia Egg - Shugo Chara

C

memmove 함수의 구현 (+ memmove함수와 memcpy함수의 차이)

별ㅇI 2023. 10. 16. 16:08
728x90
반응형

memmove 함수

  • 문자열 src에서 문자열 dst로 len byte만큼 복사하는 함수이다. 
  • 원형은 void *memmove(void *dst, const void *src, size_t len)이다
  • string.h 헤더파일에 속해 있다. 
  • 반환값은 dst의 원래주소를 반환한다.

 memmove와 memcpy의 차이

https://star-ccomputer-go.tistory.com/125

 

memcpy 함수의 구현

memcpy 함수 string.h 헤더 파일에 들어있는 함수로 memory + copy가 합쳐진 그대로 메모리의 값을 복사하는 기능을 가진 함수이다. 원형은 void *memcpy(void *restrict dst, const void *restrict src, size_t n)을 따른다.

star-ccomputer-go.tistory.com

정리 된 것에 따르면 두 함수의 원리는 같아보인다. 그렇다면 차이점은 무엇이고 왜 둘을 분리해둔것인가?

기본적으로는 원본 (src)버퍼와 목표(dst)버퍼가 중첩되는 상황에서의 예기치 못한 행동이 발생하기 떄문이다,.

memcpy는 메모리의 내용을 직접 copy하고 memmove는 메모리의 내용을 임시저장소에 저장한 후 복사를 진행한다. 

따라서 memcpy의 경우 복사 주소와 붙여넣을 주소가 일정부분겹치면 오버랩되어 의도치않은 결과가 나올 수 있는 반면 memmove는 한번에 담아 옮기거나 뒷 문자부터 복붙해서 그것을 방지 할 수 있다.

메모리 복사는 버퍼의 앞쪽부터 이루어지기 때문에 <>에 있는 내용을 []를 옮기고자 힐때,

<000000[123>456789]

의 경우에서는 비록 []는 손상되었으나 잘 옮겨진 반면

[123456<789]000000>

에서는 123456123으로 잘 못 옮겨 지기떄문에 이러한 경우를 고려하는 것이다.

따라서 memcpy쪽은 안정성 면에서는 떨어지나 속도면에서 빠르고 mememove는 속도면에서는 느리나 안정성은 더 높은 것이다. 

 

따라서 구현을 위해서는 버퍼의 위치를 파악하여 앞에서부터 붙여넣는 것과 뒤에서 붙여넣기 한것을 나누거나 아예 별도의 버퍼에 붙여넣기를 하고 복사를 진행하는 것이 바른 방법일 듯하다.

memmove 함수의 구현

#include "libft.h"

void	*ft_memmove(void *dst, const void *src, size_t len)
{
	size_t			i;
	unsigned char	*n_dst;
	unsigned char	*n_src;

	i = 0;
	n_dst = (unsigned char *)dst;
	n_src = (unsigned char *)src;
	if (n_dst == n_src)
		return (dst);
	while (i < len)
	{
		if (n_dst <= n_src)
			n_dst[i] = n_src[i];
		else
			n_dst[len - i - 1] = n_src[len - i - 1];
		i++;
	}
	return (dst);
}
// #include<string.h>
// #include<stdio.h>
// int main(void)
// {
// 	char src1[] = "0123456789";
//     char *dest1 = src1 + 3;
// 	int	i = 0;
//     memmove(dest1, src1, sizeof(char) * 5);
// 	printf("test1: memmove_src :");
// 	while (i < 10)
// 		printf("%c", src1[i++]);
// 	printf("\ntest1: memmove_dest :"); 
// 	i = 0;
// 	while (i < 10)
// 		printf("%c", dest1[i++]);
// 	i = 0;

// 	char src2[] = "0123456789";
//     char *dest2 = src2 + 3;
// 	ft_memmove(dest2, src2, sizeof(char) * 5);
// 	printf("\ntest1: ft_memmove_src :");
// 	while (i < 10)
// 		printf("%c", src2[i++]);
// 	i = 0;
// 	printf("\ntest1: ft_memmove_dest :"); 
// 	while (i < 10)
// 		printf("%c", dest2[i++]);

// 	i = 0;
// 	char src3[] = "0123456789";
//     char *dest3 = src3 - 3;
// 	memmove(dest3, src3, sizeof(char) * 5);
// 	printf("\ntest2: memmove_src :");
// 	while (i < 10)
// 		printf("%c", src3[i++]);
// 	i = 0;
// 	printf("\ntest2: memmove_dest :"); 
// 	while (i < 10)
// 		printf("%c", dest3[i++]);

// 	i = 0;
// 	char src4[] = "0123456789";
//     char *dest4 = src4 - 3;
// 	ft_memmove(dest4, src4, sizeof(char) * 5);
//     printf("\ntest2: ft_memmove_src :");
// 	while (i < 10)
// 		printf("%c", src4[i++]);
// 	i = 0;
// 	printf("\ntest2: ft_memmove_dest :"); 
// 	while (i < 10)
// 		printf("%c", dest4[i++]);
//     return 0;
// }

 

728x90
반응형