memcpy, memcpy_s
cppreference.net에서
| 헤더에 정의됨 <string.h>
|
||
void* memcpy( void* dest, const void* src, size_t count );
|
(1) | (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)
count 개의 문자를 src이 가리키는 객체에서 dest이 가리키는 객체로 복사합니다. 두 객체 모두 unsigned char의 배열로 해석됩니다.dest 배열의 끝을 넘어 접근이 발생하면 동작이 정의되지 않습니다. 객체가 겹치는 경우 (이는 restrict 계약 위반입니다)(C99 이후), 동작이 정의되지 않습니다. dest 또는 src이 유효하지 않거나 널 포인터인 경우 동작이 정의되지 않습니다.2) (1)과 동일하지만, 다음 오류들이 런타임에 감지되어 전체 대상 범위
[dest, dest + destsz)를 0으로 채우고(단, dest와 destsz가 모두 유효한 경우), 현재 설치된 제약 조건 핸들러 함수를 호출합니다:
dest또는src이 널 포인터인 경우destsz또는count이 RSIZE_MAXcount보다 큰 경우destsz이- 보다 큰 경우 (버퍼 오버플로 발생)
소스와 대상 객체가 겹치는 경우
dest < count < = destsz; 다시 말해, destsz의 오류 값이 임박한 버퍼 오버플로를 노출하지 않습니다. 모든 경계 검사 함수와 마찬가지로,
memcpy_s는 구현이 __STDC_LIB_EXT1__을 정의하고 사용자가 __STDC_WANT_LIB_EXT1__을 정수 상수 1로 정의한 후 <string.h>를 포함하는 경우에만 사용 가능함이 보장됩니다.매개변수
| dest | - | 복사할 대상 객체를 가리키는 포인터 |
| destsz | - | 대상에서 수정할 최대 바이트 수 (일반적으로 대상 객체의 크기) |
| src | - | 복사할 원본 객체를 가리키는 포인터 |
| count | - | 복사할 바이트 수 |
반환값
1)
dest의 복사본을 반환합니다.2)
dest 성공 시 0을 반환하고 오류 시 0이 아닌 값을 반환합니다. 또한 오류 시, destsz이 널 포인터가 아니고 destsz이 유효하면 대상 배열에 개의 0 바이트를 씁니다.
memcpy참고 할당 함수로 얻은 객체의 유효 타입
memcpy을 설정하는 데 사용할 수 있습니다.
는 메모리 간 복사를 위한 가장 빠른 라이브러리 루틴입니다. 일반적으로 복사할 데이터를 스캔해야 하는 strcpy나 중복 입력을 처리하기 위한 조치가 필요한 memmove
보다 더 효율적입니다.
memcpy여러 C 컴파일러가 적절한 메모리 복사 루프를
호출로 변환합니다.
엄격한 별칭 규칙이 동일한 메모리를 두 가지 다른 타입의 값으로 검사하는 것을 금지하는 경우, memcpy을 사용하여 값을 변환할 수 있습니다.
예제
이 코드 실행하기
#define __STDC_WANT_LIB_EXT1__ 1
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
// simple usage
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]);
// setting effective type of allocated memory to be int
int* p = malloc(3 * sizeof(int)); // allocated memory has no effective type
int arr[3] = {1, 2, 3};
memcpy(p, arr, 3 * sizeof(int)); // allocated memory now has an effective type
// reinterpreting data
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 is greater than 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
참조
- C23 표준 (ISO/IEC 9899:2024):
- 7.24.2.1 memcpy 함수 (p: TBD)
- K.3.7.1.1 memcpy_s 함수 (p: TBD)
- C17 표준 (ISO/IEC 9899:2018):
- 7.24.2.1 memcpy 함수 (p: TBD)
- K.3.7.1.1 memcpy_s 함수 (p: TBD)
- 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++ 문서에 대한 memcpy
| |