Quick Reference
세 함수는 모두 바이트 수를 받습니다. source와 destination이 겹치지 않으면 memcpy, 겹칠 수 있으면 memmove, 같은 byte 값을 채울 때만 memset을 고릅니다.
int src[] = {1, 2, 3};
int dst[3];
memcpy(dst, src, sizeof dst); /* 두 배열은 겹치지 않는다. */
char text[] = "move";
memmove(text, text + 1, strlen(text)); /* 같은 buffer에서 왼쪽으로 이동 */
int values[3];
memset(values, 0, sizeof values); /* 0 byte 채움은 0 int 초기화에 쓸 수 있다. */memcpy의 source와 destination이 겹치면 동작이 정의되지 않습니다. memset(values, 1, sizeof values)는 각 int를 1로 만드는 코드가 아니라 각 byte를 0x01로 채우는 코드입니다.
문법
겹치지 않는 두 버퍼 복사는 memcpy가 가장 직접적입니다.
int src[4] = {1, 2, 3, 4};
int dst[4];
memcpy(dst, src, sizeof(src));같은 버퍼 안에서 밀거나 당기는 작업은 memmove로 봐야 합니다.
char buf[10] = "abcde";
memmove(buf, buf + 1, strlen(buf + 1) + 1);문자열을 이동할 때는 널 종료 문자까지 옮겨야 합니다. 위 예제는 첫 글자를 제거한 뒤 "bcde"라는 유효한 문자열을 남깁니다.
memset은 바이트 패턴 채우기 함수라서 0 초기화에는 잘 맞습니다.
memset(dst, 0, sizeof(dst));경계 이해
이 카드의 핵심은 함수 이름보다 사용 조건입니다.
- 겹치지 않는 복사:
memcpy - 겹칠 수 있는 이동:
memmove - 바이트 패턴 채우기:
memset
특히 원소 개수와 바이트 수를 혼동하면 일부만 복사하거나 경계를 넘기 쉽습니다.
memcpy(dst, src, 4); // 잘못된 길이
memcpy(dst, src, 4 * sizeof(int)); // 올바른 길이memset(arr, 1, sizeof(arr))처럼 정수 배열 초기화 도구로 읽는 것도 흔한 오해입니다. memset은 "정수 값을 채운다"보다 "모든 바이트를 같은 값으로 채운다"에 가깝습니다.
구조체와 객체 표현을 바이트로 복사한다고 항상 독립적인 직렬화 형식이 되지는 않습니다. padding, endian, 포인터 값은 그대로 옮겨도 다른 프로세스나 플랫폼에서 같은 의미가 아닙니다. 네트워크·파일 형식은 필드 단위로 변환합니다.
빠른 점검
- 겹치지 않는 복사는
memcpy입니다. - 겹칠 수 있는 이동은
memmove입니다. - 0 초기화 같은 바이트 채우기는
memset입니다. - 길이는 항상 바이트 수로 계산해야 합니다.
memset은 바이트 패턴 함수라서 임의의 정수 배열 초기화 도구로 보면 안 됩니다.
주의할 점
겹치는 영역에 memcpy를 쓰면 정의되지 않은 동작입니다. 같은 버퍼 안에서 이동하는 작업은 memmove가 맞고, 길이는 항상 바이트 수 기준으로 다시 확인하는 편이 안전합니다.
참고 링크
4 sources