메모리를 바이트 단위로 복사할 때, c나 c++ 에서는 memcpy와 memmove를 많이 사용합니다. 물론, pod 타입이여야 한다는 전제가 깔리긴 하지만요. 이 둘은 어떻게 쓸까요? c언어 memcpy나, memmove는 1번째 인자가 dest 포인터, 2번째 인자는 orignal 포인터, 3번째 인자를 몇 바이트만큼을 복사할 것인지를 넘겨줍니다. 메모리에 있는 내용을 바이트 단위로 복사하는 것은 두 함수의 공통점입니다. 삽입 정렬을 구현할 때, 이 두 함수를 잘 이용하면 좋겠지요.

 

 


 첫 번째 예제 프로그램을 봅시다.

 

 int형 20개를 저장할 수 있는 ori 배열과 des 배열을 선언했습니다. 저는 ori 배열에 0, 1, ... , 19를 넣었습니다. 원소 갯수는 20개입니다. 그리고, 저는 des가 가리키는 곳부터 sizeof(int)*20바이트만큼을 복사합니다. 어떤 내용을? ori가 가리키는 곳부터 int형의 크기에 20을 곱한 값만큼의 내용을 바이트 단위로 복사합니다.

 

 

 

 즉, 원본은, 그러니까 복사할 내용은 빨간색으로 칠한 부분입니다. 그리고 어디에 복사를 할까요? des에. des 배열에 복사했어요. 즉, 저는 ori 배열의 내용을 des 배열에 넣은 셈이 됩니다.

 

 

 첫 번째 예제 프로그램은 쉽게 이해가시리라 믿습니다. 문제는, memcpy 함수의 경우, overlap이 되는 경우를 처리하지 않습니다. 복사할 메모리 공간과, 원본 메모리 공간이 겹친다? 이건 무엇을 의미할까요? 예제 프로그램 2번을 봅시다.

 

 

 original 포인터는 ori+2입니다. 그리고 복사가 될 메모리는 ori+4입니다. 즉, 저는 ori+2부터 sizeof(int)*17만큼의 메모리 내용을 ori+4에 복사하겠다는 건데요. 복사할 원본 메모리 부터 표시해 봅시다.

 

 

 ori+2부터 17개이기 때문에, [2, ... , 18]의 내용이 copy가 되야 합니다. 이것을 어디에 복사해야 할까요?

 

 

 

 ori+4부터 그대로 넣어주면 됩니다. 보시면 빨간색 부분하고, 연두색 부분이 겹치는데요. 이것을 중첩이 된다. overlap 된다고 이야기 합니다. 이러한 경우, 동작이 정의되지 않습니다. 제 페도라에서 실행시켰을 때에는 결과 값이 제대로 나왔습니다.

 

 빨간 부분을 연두색으로 표시된 부분에 복사한다면 0 1 2 3 2 3 4 ... 번째 원소가 나와야 할 겁니다. 저는 처음에 ori[i]에 i+1을 넣었기 때문에, 결과값이 제대로 나왔다면 1 2 3 4 3 4 5 6 ... 이 나왔어야 합니다.

 

 

 

 제 페도라에서는 제대로 나왔습니다. wandbox에서는 어떨까요?

 

 

 1 2 3 4 3 4 5 6 5 6 9 10 13? 무엇인가 제대로 나온 것 같지 않습니다. memcpy는 복사될 공간과, orignal 공간이 겹치는 경우에 쓰면 안 됩니다. 동작이 정의되지 않기 때문입니다. 그러면 예제 프로그램 2를 어떻게 바꾸어야 할까요?

 

 


 memmove는 memcpy와 사용법이 같습니다. 복사할 곳, 그러니까 dest, 복사할 데이터, 그러니까 orignal 데이터, 그리고 몇 바이트만큼 복사할 것인가는 똑같습니다.

 

 

 OVERLAP 되는 경우, memcpy 대신 memmove를 써 주었습니다. 이번에는 wandbox에서 제대로 값이 나올까요?

 

 

 1 2 3 4 3 4 5 6 ... 제대로 나왔습니다. 메모리가 겹칠 경우에는 메모리 카피 함수를 쓰지 말고, 무브를 써야 한다 정도만 짚고 넘어가면 됩니다. 배열에 있는 원소 하나를 삭제했습니다. 이 경우에는 무엇을 써야 할까요?

 

 

 초록색 부분을 삭제했다고 칩시다. 그러면, 빨간색으로 칠한 부분을 1칸 앞으로 당겨야 할 겁니다. 그러면, arr+1에 있는 내용들을 arr+0에 복사해야 할 거에요. 원소 2개만큼요. arr+0부터 원소 2개만큼이 dest, 그러니까 복사할 공간입니다.

 

 

 제가 초록색으로 칠한 곳이죠. 겹치나요? overlap 되기 때문에 move를 써야 합니다.