[42 Seoul] memmove를 알아보자

youngmki·2021년 5월 4일
0

Libft

목록 보기
5/5
post-thumbnail

1. 구조

#include <string.h>
	void	*memmove(void *dst, const void *src, size_t n)

2. 기능

메모리의 값을 src에서 dstn 바이트 만큼 복사합니다.
이때, src 배열은 오버 랩을 방지하기 위해 srcdest의 메모리 영역에서 겹치지 않는 부분 부터 먼저 복사됩니다.
memcpy와 같은 기능을 하지만, 오버랩을 방지하기 위해 동작을 다르게 정의합니다.

3. Parameter

1) void *dst

복사 받을 메모리의 시작을 가리키는 포인터입니다.
함수 내부적으로 unsigned char로 처리되어 작성됩니다.

2) const void *src

복사를 할 메모리의 시작을 가리키는 포인터입니다.
마찬가지로 함수 내부적으로 unsigned char로 처리되어 작성됩니다.

2) size_t len

복사할 메모리의 크기를 나타냅니다.

4. 사용예제

  • 기존에 쓰여져 있던 값이 새로운 값이 덮여쓰여진 모습입니다.
int main()
{
	char dst[20] = "aaaaaa";
	char src[20] = "copy this\0";

	printf("Before processed	: %s\n", dst);

	memcpy(dst, src, 10);
	printf("processed		: %s\n", dst);
}

5. 주의사항

memmoveoverlap

1) dst의 메모리 주소가 src보다 작다면, src의 시작 부분부터 복사가 진행됩니다.

2) dst의 메모리 주소가 src보다 크다면, src의 시작 부분부터 복사가 진행됩니다.

memset은 memmove과 기능상으로는 동일하다고 볼 수 있습니다.
그러나, 내부적으로 memset은 오버랩을 별도로 고려하지 않는다는 점에서 차이가 있습니다.

이때 오버랩이라 함은, 복사가 진행되어야 할 src의 메모리 공간이 memset 진행 중 변형되는 문제 상황을 의미합니다.

앞서 2) dst의 메모리 주소가 src보다 크다면, src의 시작 부분부터 복사가 진행의 상황에서 뒤가 아닌 앞에서부터 복사가 진행되는 경우를 따져보면 3에 해당하는 값이 5로 덮여쓰여지고, 이후 해당 메모리가 dst에 다시금 복사되고 있음을 발견할 수 있습니다. 그럴 경우, 처음에 원했던 3이 복사되는 것이 아닌 5가 복사되어 문제가 됩니다.

int main(void)
{
    char str1[] = "ABCDEFG";
 
// memcpy
    ft_memcpy(str1 + 2, str1, sizeof(char) * 5);
    printf("src  : %s\n", str1);

	char str2[] = "ABCDEFG";

// memmove
    memmove(str2 + 2, str2, sizeof(char) * 5);
    printf("src  : %s\n", str2);
    return 0;
}

현재 특정 환경을 제외한 memcpy은 오버랩핑이라는 단점을 보완되어 이제는 더이상 이러한 오류는 발생하지 않고 있는 것 같다.
다만, 오버랩핑의 의미를 알아보기 위해 의도적으로 에러를 발생시키기 위해 커스텀 함수를 사용하였다.
(혹시 잘못된 부분이 있다면 지적바랍니다)

참고로, 현재 작성하는 컴퓨터의 gcc 버전은 'Apple clang version 12.0.0 (clang-1200.0.32.28)' 입니다.

0개의 댓글