* src를 num byte만큼 dest에 옮기는 함수.
* memcpy와는 다르게 인접한 메모리에서도 옮길 수 있게 한다.
void *ft_memmove(void *dest, const void *src, size_t num)
void *dest : 복사할 문자열의 주소
const void *src : 복사될 문자열의 주소
size_t num : 복사할 바이트 수
src와 dest가 둘 다 NULL일 때, NULL(dest)값을 반환.
dest와 src의 주소를 비교하여 연산한다.
--> dest < src라면 뒤에서부터 복사해야 제대로 복사된다.
앞에서부터 복사하면 '맨 앞의 값'만 복사되기 때문에 뒤에서부터 복사해야 한다.
--> dest >= src라면 앞에서부터 복사해야 제대로 복사된다.
뒤에서부터 복사하면 '맨 뒤의 값'만 복사되기 때문에 앞에서부터 복사해야 한다.
즉 dest의 주소가 index 1번이고, src의 주소가 index 0번이기 때문에 dest > src이다.
<1>
앞에서부터 복사하면 1 1 1 1 1로 복사된다.
순서 ) 1 2 3 4 5 -> 1 1 3 4 5 -> 1 1 1 4 5 -> 1 1 1 1 5 -> 1 1 1 1 1
<2>
뒤에서부터 복사하면 1 1 2 3 4로 복사된다.
순서 ) 1 2 3 4 5 -> 1 2 3 4 4 -> 1 2 3 3 4 -> 1 2 2 3 4 -> 1 1 2 3 4
즉 뒤에서부터 복사해야 한다.
즉 dest의 주소가 index 0번이고, src의 주소가 index 1번이기 때문에 dest < src이다.
<1>
앞에서부터 복사하면 2 3 4 5 5로 복사된다.
순서 ) 1 2 3 4 5 -> 2 2 3 4 5 -> 2 3 3 4 5 -> 2 3 4 4 5 -> 2 3 4 5 5
<2>
뒤에서부터 복사하면 5 5 5 5 5로 복사된다.
순서 ) 1 2 3 4 5 -> 1 2 3 5 5 -> 1 2 5 5 5 -> 1 5 5 5 5 -> 5 5 5 5 5
즉 앞에서부터 복사해야 한다.
<중요>
dest와 src를 unsigned char *로 형변환해야 한다.
--> unsigned char
는 모든 bit를 투명하게 볼 수 있는 특성
을 제공한다.
즉 다른 type은 내부 비트의 일부를 값을 표현하기 위한 용도가 아닌 다른 용도
로 사용할 수 있으나 unsigned char는 이것이 허락되지 않아 mem함수, str함수에서는 unsigned char을 이용한다.
또한 메모리 주소의 경우 부호 있는 정수 타입을 쓰면 안된다.
void 포인터 연산 시 unsigned char 포인터를 이용한다.
--> void 포인터 연산은 호환성을 위해 사용하지 않는 것이 좋다. 메모리 주소에 부호 있는 정수 타입을 쓰면 올바르게 동작하지 않기 때문에 비부호로 처리해야 한다.
void 포인터의 경우 음수를 저장할 때 2의 보수 형태로 저장하게 된다. 단순히 부호 여부가 아닌 데이터를 저장하는 방식이 달라진다고 한다.
참고 : 링크텍스트
#include "libft.h"
void *ft_memmove(void *dest, const void *src, size_t num)
{
size_t index;
if (!src && !dest)
return (NULL);
index = 0;
if ((unsigned char *)dest < (unsigned char *)src)
{
while (index < num)
{
((unsigned char *)dest)[index] = ((unsigned char *)src)[index];
index++;
}
}
else
{
while (index < num)
{
((unsigned char *)dest)[num - 1 - index] =
((unsigned char *)src)[num - 1 - index];
index++;
}
}
return ((unsigned char *)dest);
}
(1) src와 dest모두 NULL이면 복사할 필요가 없으므로 NULL(dest)를 반환한다.
(2) dest와 src를 unsigned char *로 변환한 주소값을 비교한다.
(3) dest가 src보다 작으면 앞에서부터 복사한다.
(4) dest가 src보다 크면 뒤에서부터 복사한다.
(5) dest를 반환한다.