Microsoft MVP성태의 닷넷 이야기
VC++: 98. 원본과 대상 버퍼가 같은 경우 memcpy, wmemcpy 주의점 [링크 복사], [링크+제목 복사],
조회: 28093
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

원본과 대상 버퍼가 같은 경우 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++ 컴파일러로 가면 역시나 그 결과는 보장할 수 없습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/17/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  [7]  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
13864정성태1/15/20257943Linux: 114. eBPF를 위해 필요한 SELinux 보안 정책
13863정성태1/14/20255902Linux: 113. Linux - 프로세스를 위한 전용 SELinux 보안 문맥 지정
13862정성태1/13/20256904Linux: 112. Linux - 데몬을 위한 SELinux 보안 정책 설정
13861정성태1/11/20257301Windows: 276. 명령행에서 원격 서비스를 동기/비동기로 시작/중지
13860정성태1/10/20256453디버깅 기술: 216. WinDbg - 2가지 유형의 식 평가 방법(MASM, C++)
13859정성태1/9/20257962디버깅 기술: 215. Windbg - syscall 이후 실행되는 KiSystemCall64 함수 및 SSDT 디버깅
13858정성태1/8/20258308개발 환경 구성: 738. PowerShell - 원격 호출 시 "powershell.exe"가 아닌 "pwsh.exe" 환경으로 명령어를 실행하는 방법
13857정성태1/7/20258367C/C++: 187. Golang - 콘솔 응용 프로그램을 Linux 데몬 서비스를 지원하도록 변경파일 다운로드1
13856정성태1/6/20256272디버깅 기술: 214. Windbg - syscall 단계까지의 Win32 API 호출 (예: Sleep)
13855정성태12/28/20248836오류 유형: 941. Golang - os.StartProcess() 사용 시 오류 정리
13854정성태12/27/20248634C/C++: 186. Golang - 콘솔 응용 프로그램을 NT 서비스를 지원하도록 변경파일 다운로드1
13853정성태12/26/20246837디버깅 기술: 213. Windbg - swapgs 명령어와 (Ring 0 커널 모드의) FS, GS Segment 레지스터
13852정성태12/25/20249328디버깅 기술: 212. Windbg - (Ring 3 사용자 모드의) FS, GS Segment 레지스터파일 다운로드1
13851정성태12/23/20247191디버깅 기술: 211. Windbg - 커널 모드 디버깅 상태에서 사용자 프로그램을 디버깅하는 방법
13850정성태12/23/20249258오류 유형: 940. "Application Information" 서비스를 중지한 경우, "This file does not have an app associated with it for performing this action."
13849정성태12/20/20249190디버깅 기술: 210. Windbg - 논리(가상) 주소를 Segmentation을 거쳐 선형 주소로 변경
13848정성태12/18/20248222디버깅 기술: 209. Windbg로 알아보는 Prototype PTE파일 다운로드2
13847정성태12/18/20247836오류 유형: 939. golang - 빌드 시 "unknown directive: toolchain" 오류 빌드 시 이런 오류가 발생한다면?
13846정성태12/17/20249566디버깅 기술: 208. Windbg로 알아보는 Trans/Soft PTE와 2가지 Page Fault 유형파일 다운로드1
13845정성태12/16/20246795디버깅 기술: 207. Windbg로 알아보는 PTE (_MMPTE)
13844정성태12/14/202410076디버깅 기술: 206. Windbg로 알아보는 PFN (_MMPFN)파일 다운로드1
13843정성태12/13/20247365오류 유형: 938. Docker container 내에서 빌드 시 error MSB3021: Unable to copy file "..." to "...". Access to the path '...' is denied.
13842정성태12/12/20247742디버깅 기술: 205. Windbg - KPCR, KPRCB
13841정성태12/11/20248464오류 유형: 937. error MSB4044: The "ValidateValidArchitecture" task was not given a value for the required parameter "RemoteTarget"
13840정성태12/11/20247536오류 유형: 936. msbuild - Your project file doesn't list 'win' as a "RuntimeIdentifier"
13839정성태12/11/20249143오류 유형: 936. msbuild - error CS1617: Invalid option '12.0' for /langversion. Use '/langversion:?' to list supported values.
1  2  3  4  5  6  [7]  8  9  10  11  12  13  14  15  ...