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
и
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) { // простое использование 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); // нарушение строгого псевдонимирования 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); // количество больше чем 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
|
|