memcpy, memcpy_s
Определено в заголовке <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) |
count символов из объекта, на который указывает src, в объект, на который указывает dest. Оба объекта интерпретируются как массивы unsigned char. dest. Если объекты перекрываются (что нарушает контракт restrict)(с C99), поведение не определено. Поведение не определено, если любой из dest или src является недействительным или нулевым указателем. [dest, dest+destsz) (если оба dest и destsz являются действительными), а также вызывают функцию обработчика ограничений, установленную в настоящее время: -
destилиsrcявляется нулевым указателем -
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 | - | количество байтов для копирования |
Возвращаемое значение
dest
dest не является нулевым указателем и destsz является допустимым, записывает destsz нулевых байтов в массив назначения. Примечания
memcpy может использоваться для установки эффективного типа объекта, полученного с помощью функции выделения памяти.
memcpy — это самая быстрая библиотечная функция для копирования памяти в память. Она обычно эффективнее, чем strcpy, которая должна сканировать копируемые данные, или memmove, которая должна принимать меры предосторожности для обработки перекрывающихся входных данных.
Некоторые компиляторы C преобразуют подходящие циклы копирования памяти в вызовы memcpy.
Там, где строгое алиасирование запрещает проверку одного и того же участка памяти как значений двух разных типов, 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)
{
// 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
Ссылки
- Стандарт C11 (ISO/IEC 9899:2011):
- 7.24.2.1 Функция memcpy (стр. 362)
- K.3.7.1.1 Функция memcpy_s (стр. 614)
- Стандарт C99 (ISO/IEC 9899:1999):
- 7.21.2.1 Функция memcpy (стр. 325)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 4.11.2.1 Функция memcpy
См. также
|
(C23) | копирует один буфер в другой, останавливаясь после указанного разделителя (функция) |
|
(C11) | перемещает один буфер в другой (функция) |
|
(C95)(C11) | копирует определённое количество широких символов между двумя неперекрывающимися массивами (функция) |
Документация C++ для memcpy |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/string/byte/memcpy