원본과 대상 버퍼가 같은 경우 memcpy, wmemcpy 주의점
Visual C++로 다음의 코드를 컴파일해 실행하면,
#include <iostream>
#include <string.h>
int main()
{
char word[6] = {'a', 'b', 'c', 'd', 'e', '\0' };
memcpy(word, word + 1, 5);
std::cout << word;
return 0;
}
x86/x64, Debug/Release에 상관없이 "bcde" 결과를 볼 수 있습니다.
반면 다음의 사이트에서 컴파일해 보면,
C++ Shell
; http://cpp.sh/
C++ 최적화 옵션에 따라 결과가 다음과 같이 나옵니다.
// C++14, Optiminzation level == None
bdee
// C++14, Optiminzation level != None
bcde
찾아보니, 이런 불확실성이 문서에 기재되어 있습니다.
memcpy, memcpy_s
; http://en.cppreference.com/w/c/string/byte/memcpy
If the objects overlap, the behavior is undefined.
MSDN 문서도 같은 설명을 포함합니다.
memcpy, wmemcpy
; https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy
If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions.
그나마 더 친절하군요. ^^ 이런 경우라면 대신 memmove를 쓰라고 안내까지 합니다.
memmove, wmemmove
; https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memmove-wmemmove
If some regions of the source area and the destination overlap, both functions ensure that the original source bytes in the overlapping region are copied before being overwritten.
따라서, 특별히 대단한 성능이 요구되는 경우가 아니라면 안전하게 memmove를 쓰는 것이 더 권장됩니다.
근래에 두 함수 모두 똑같은 기능을 갖는 것으로 보인다고 하는 의견이 있는데, 그건 Visual C++에 한해서일 뿐 다른 C/C++ 컴파일러로 가면 역시나 그 결과는 보장할 수 없습니다.
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]