memcpy & memmove

memcpy

  • destination 주소값, source 주소값, source의 길이를 인자로 받는 함수
  • sdource의 값을 destination으로 복사
// memvpy의 알고리즘은 아래와 같다
void MyMemcpy(char* dest, char* src, size_t len)
{
    for (size_t i = 0; i < len; ++i)
    {
        *(dest + i) = *(src + i);
    }
}

// 위의 함수로 memcpy를 실행하면...
int main()
{
    char a[20] = "ABCDEFG";
    MyMemcpy(a+2, a, 7);
    printf("%s", a);

    // Output: ABABABABA
}
  • memcpy의 문제점 - Overlapping
    • source와 destination의 공간이 겹치는 경우에 overlapping 버그가 발생한다

memmove

  • self copy를 실행할 때 memcpy의 대체방안
// temp memory를 사용하는 경우
void* MyMemmove1(char* dest, char* src, size_t n) {
    
    char* tmp = static_cast<char*>(malloc(sizeof(char) * n));
    // tmp에 원본을 미리 저장
    for (size_t i = 0; i < n; ++i)
    {
        *(tmp + i) = *(src + i);
    }
    // 타겟에 tmp에 저장한 값을 옮김
    for (size_t i = 0; i < n; ++i)
    {
        *(dest + i) = *(tmp + i);
    }
    
    return dest;
}

// temp memory를 사용하지 않는 경우
void* MyMemmove2(char* dest, char* src, size_t n) {
    signed char operation;
    size_t end;
    size_t current;

    if (dest != src) {

        // **시작하는 방향을 설정**

        // 1. source가 target보다 뒤인 경우
        // 이미 복사한 값과 복사되어야 하는 값의 영역이 겹치지 않아
        // overlapping 위험이 없다
        if (dest < src) {
            operation = 1;
            current = 0;
            end = n;
        }

        // 2. source가 target보다 앞인 경우
        // 뒤에서부터 미리 복사해놓고 앞으로 이동한다
        // 겹치는 부분에 대해 overlapping을 방지
        else {
            operation = -1;
            current = n - 1;
            end = -1;
        }

        // 결론은, source의 뒷부분부터 미리 target에 복사하면 된다는 것
        for (; current != end; current += operation) {
            *(dest + current) = *(src + current);
        }
    }
    return dest;
}
  • Overlapping이 발생하지 않는다

출처

Categories: ,

Updated: