이 세 함수는 모두 바이트 블록을 다루지만 겹침 여부와 초기화 의도가 다릅니다.
- 겹치지 않는 두 버퍼를 복사한다
- 같은 버퍼 안에서 데이터를 밀거나 당긴다
- 메모리를 0으로 초기화하거나 일정한 바이트 패턴으로 채운다
숏컷 코드
c
memcpy(dst, src, sizeof(src));
memmove(buf, buf + 1, len);
memset(dst, 0, sizeof(dst));문법
겹치지 않는 두 버퍼 복사는 memcpy가 가장 직접적입니다.
c
int src[4] = {1, 2, 3, 4};
int dst[4];
memcpy(dst, src, sizeof(src));같은 버퍼 안에서 밀거나 당기는 작업은 memmove로 봐야 합니다.
c
char buf[10] = "abcde";
memmove(buf, buf + 1, strlen(buf));memset은 바이트 패턴 채우기 함수라서 0 초기화에는 잘 맞습니다.
c
memset(dst, 0, sizeof(dst));경계 이해
이 카드의 핵심은 함수 이름보다 사용 조건입니다.
- 겹치지 않는 복사:
memcpy - 겹칠 수 있는 이동:
memmove - 바이트 패턴 채우기:
memset
특히 원소 개수와 바이트 수를 혼동하면 일부만 복사하거나 경계를 넘기 쉽습니다.
c
memcpy(dst, src, 4); // 잘못된 길이
memcpy(dst, src, 4 * sizeof(int)); // 올바른 길이memset(arr, 1, sizeof(arr))처럼 정수 배열 초기화 도구로 읽는 것도 흔한 오해입니다. memset은 "정수 값을 채운다"보다 "모든 바이트를 같은 값으로 채운다"에 가깝습니다.
체크포인트
- 겹치지 않는 복사는
memcpy입니다. - 겹칠 수 있는 이동은
memmove입니다. - 0 초기화 같은 바이트 채우기는
memset입니다. - 길이는 항상 바이트 수로 계산해야 합니다.
memset은 바이트 패턴 함수라서 임의의 정수 배열 초기화 도구로 보면 안 됩니다.
주의할 점
겹치는 영역에 memcpy를 쓰면 정의되지 않은 동작입니다. 같은 버퍼 안에서 이동하는 작업은 memmove가 맞고, 길이는 항상 바이트 수 기준으로 다시 확인하는 편이 안전합니다.
참고 링크
3 sources