memcpy, memcpy_s
From cppreference.net
|
헤더 파일에 정의됨
<string.h>
|
||
| (1) | ||
|
void
*
memcpy
(
void
*
dest,
const
void
*
src,
size_t
count
)
;
|
(C99 이전) | |
|
void
*
memcpy
(
void
*
restrict
dest,
const
void
*
restrict
src,
size_t
count
)
;
|
(C99 이후) | |
|
errno_t memcpy_s
(
void
*
restrict
dest, rsize_t destsz,
const void * restrict src, rsize_t count ) ; |
(2) | (C11 이후) |
1)
src
가 가리키는 객체에서
dest
가 가리키는 객체로
count
개의 문자를 복사합니다. 두 객체 모두
unsigned
char
배열로 해석됩니다.
동작은
dest
배열의 끝을 넘어서 접근이 발생할 경우 정의되지 않습니다. 객체들이 겹치는 경우
(이는
restrict
계약 위반임)
(C99부터)
, 동작은 정의되지 않습니다.
dest
또는
src
가 유효하지 않거나 널 포인터인 경우 동작은 정의되지 않습니다.
2)
(1)
과 동일하지만, 다음 오류들이 런타임에 감지되어 전체 대상 범위
[
dest, dest
+
destsz
)
를 제로 아웃시키고(
dest
와
destsz
가 모두 유효한 경우), 현재 설치된
constraint handler
함수를 호출합니다:
-
-
dest또는src가 null 포인터인 경우 -
destsz또는count가 RSIZE_MAX 보다 큰 경우 -
count가destsz보다 큰 경우(버퍼 오버플로우가 발생할 경우) - 소스와 대상 객체가 중복되는 경우
-
dest
가 가리키는 문자 배열의 크기가
count
<=
destsz
보다 작은 경우 동작은 정의되지 않습니다. 즉,
destsz
의 잘못된 값은 임박한 버퍼 오버플로를 노출하지 않습니다.
-
모든 경계 검사 함수와 마찬가지로,
memcpy_s는 구현에서 __STDC_LIB_EXT1__ 가 정의되고 사용자가 __STDC_WANT_LIB_EXT1__ 를 정수 상수 1 으로 정의한 후에만 사용 가능함이 보장됩니다 <string.h> 를 포함하기 전에.
목차 |
매개변수
| dest | - | 복사 대상 객체를 가리키는 포인터 |
| destsz | - | 대상에서 수정할 최대 바이트 수 (일반적으로 대상 객체의 크기) |
| src | - | 복사 원본 객체를 가리키는 포인터 |
| count | - | 복사할 바이트 수 |
반환값
1)
dest
의 복사본을 반환합니다
2)
성공 시 0을 반환하고 오류 시 0이 아닌 값을 반환합니다. 또한 오류 발생 시,
dest
가 null 포인터가 아니고
destsz
가 유효한 경우, 대상 배열에
destsz
개의 제로 바이트를 기록합니다.
참고 사항
memcpy
는 할당 함수로 얻은 객체의
effective type
을 설정하는 데 사용될 수 있습니다.
memcpy
는 메모리 간 복사를 위한 가장 빠른 라이브러리 루틴입니다. 일반적으로 복사할 데이터를 스캔해야 하는
strcpy
나 중복 입력을 처리하기 위한 예방 조치를 취해야 하는
memmove
보다 더 효율적입니다.
여러 C 컴파일러들이 적절한 메모리 복사 루프를
memcpy
호출로 변환합니다.
strict aliasing
이 서로 다른 두 타입의 값으로 동일한 메모리를 검사하는 것을 금지하는 경우,
memcpy
를 사용하여 값을 변환할 수 있습니다.
예제
이 코드 실행
#define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <stdint.h> #include <inttypes.h> #include <string.h> #include <stdlib.h> int main(void) { // 간단한 사용법 char source[] = "once upon a midnight dreary...", dest[4]; memcpy(dest, source, sizeof dest); for(size_t n = 0; n < sizeof dest; ++n) putchar(dest[n]); // 할당된 메모리의 유효 타입을 int로 설정 int *p = malloc(3*sizeof(int)); // 할당된 메모리는 유효 타입이 없음 int arr[3] = {1,2,3}; memcpy(p,arr,3*sizeof(int)); // 할당된 메모리는 이제 유효 타입을 가짐 // 데이터 재해석 double d = 0.1; // int64_t n = *(int64_t*)(&d); // strict aliasing violation int64_t n; memcpy(&n, &d, sizeof d); // OK printf("\n%a is %" PRIx64 " as an int64_t\n", d, n); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char src[] = "aaaaaaaaaa"; char dst[] = "xyxyxyxyxy"; int r = memcpy_s(dst,sizeof dst,src,5); printf("dst = \"%s\", r = %d\n", dst,r); r = memcpy_s(dst,5,src,10); // count가 destsz보다 큼 printf("dst = \""); for(size_t ndx=0; ndx<sizeof dst; ++ndx) { char c = dst[ndx]; c ? printf("%c", c) : printf("\\0"); } printf("\", r = %d\n", r); #endif }
가능한 출력:
once 0x1.999999999999ap-4 is 3fb999999999999a as an int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
참고문헌
- C11 표준 (ISO/IEC 9899:2011):
-
- 7.24.2.1 memcpy 함수 (p: 362)
-
- K.3.7.1.1 memcpy_s 함수 (p: 614)
- C99 표준 (ISO/IEC 9899:1999):
-
- 7.21.2.1 memcpy 함수 (p: 325)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 4.11.2.1 memcpy 함수
참고 항목
|
(C23)
|
한 버퍼를 다른 버퍼로 복사하며, 지정된 구분자 이후에 중지합니다
(함수) |
|
(C11)
|
한 버퍼를 다른 버퍼로 이동합니다
(함수) |
|
(C95)
(C11)
|
두 개의 겹치지 않는 배열 사이에서 지정된 양의 와이드 문자를 복사합니다
(함수) |
|
C++ 문서
for
memcpy
|
|