memmove

유제민·2025년 4월 10일

42경산

목록 보기
5/17

memmove 뭐예요

memory + move 메모리를 이동한다. 버퍼를 이용하여 메모리의 값을 복사하는 함수

함수 원형: void memmove(void dest, const void *src, size_t n);
void *dest: 복사한 값을 붙여넣을 메모리를 가리키는 포인터
const void *src: 값을 복사할 메모리를 가리키는 포인터
size_t n: 복사할 바이트의 길이
반환값: dest

ft_memmove 구현

#include "libft.h"

void	*ft_memmove(void *dest, const void *src, size_t n)
{
	unsigned char		*d;
	const unsigned char	*s;
	size_t				i;

	s = (const unsigned char *)src;
	d = (unsigned char *)dest;
	i = 0;
	if (d > s) //메모리가 겹치는경우
	{
		while (n-- > 0)	//뒤에서 복사
			d[n] = s[n];
	}
	else
	{
		while (i < n)	// 안겹치면
		{
			d[i] = s[i];	//그대로 복사
			i++;
		}
	}
	return (dest);
}

memcpy와 다른점이 머예요

이게 가장 중요한 파트

	if (d > s) //메모리가 겹치는경우
	{
		while (n-- > 0)	//뒤에서 복사
			d[n] = s[n];
	}

이 코드를 보면 메모리가 겹치는 경우에는 뒤에서부터 복사한다고 했다.
여기서 c if (d > s)는 왜 겹친다는 뜻일까?
d와 s는 코드 본문에서 매개변수를 타입 캐스팅해서 할당한 메모리 주소다.

메모리 상황을 예를 들자면
주소 내용
0x1000 src[0]
0x1001 src[1]
0x1002 src[2]
0x1003 src[3]
만약 src = 0x1000이고 dest = 0x1001이라고 하면 dest는 src보다 한 칸 뒤에 있는 것이다.
그럼 복사를 앞쪽부터 한다면 복사가 다 끝나기도 전에 src의 내용이 덮어쓰기 되어 깨질 수 있다!

그래서 d > s일 때는 dest가 src보다 메모리 상 뒤에 있다는 것이니 뒤에서부터 복사를 해야한다.

또 뭐가 다르냐? memmove는 버퍼를 이용한 복사를 한다.
버퍼는 잠깐 데이터 저장하는 공간이다.
흔히들 사용하는 temp 변수를 생각할 수 있는데, memmove 구현 중에는 버퍼를 만들지 않는다.
복사 방향을 바꿔버리는데,

dest <= src	//앞에서부터 복사
dest > src // 뒤에서부터 복사

버퍼를 진짜 만들어서 사용하는 경우는 메모리가 심각하게 겹쳐서 잠깐 다른 곳에 저장했다가 복사할 경우에만 만든다.

결론

메모리가 겹칠 경우 뒤에서부터 복사해서 덮어쓰기 문제를 피하는 게 memmove의 특징이다.

profile
무진장 게으른

0개의 댓글