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이 발생하지 않는다

출처