memmove, memmove_s
Определено в заголовке <string.h> | ||
|---|---|---|
void* memmove( void* dest, const void* src, size_t count ); | (1) | |
errno_t memmove_s(void *dest, rsize_t destsz, const void *src, rsize_t count); | (2) | (с C11) |
count символов из объекта, на который указывает src, в объект, на который указывает dest. Оба объекта интерпретируются как массивы unsigned char. Объекты могут перекрываться: копирование происходит так, как если бы символы были скопированы в временный массив символов, а затем символы были скопированы из массива в dest.dest или src являются невалидным или нулевым указателем.[dest, dest+destsz) (если dest и destsz являются допустимыми) обнуляется и вызывается текущая функция обработчика ограничений обработчик ограничений: -
destилиsrc— нулевой указатель -
destszилиcountбольшеRSIZE_MAX -
countбольшеdestsz(произошел буферный переполнение)
dest, меньше count <= destsz; другими словами, ошибочное значение destsz не выявляет надвигающееся буферное переполнение. Как и во всех функциях с проверкой границ, memmove_s гарантируется только в том случае, если __STDC_LIB_EXT1__ определено реализацией, и если пользователь определил __STDC_WANT_LIB_EXT1__ как целочисленную константу 1 перед включением <string.h>.Параметры
| dest | - | указатель на объект, в который копировать |
| destsz | - | максимальное количество байтов для изменения в объекте назначения (обычно размер объекта назначения) |
| src | - | указатель на объект, из которого копировать |
| count | - | количество байтов для копирования |
Значение результата
dest
dest не является нулевым указателем и destsz допустимо, в массив назначения записывается destsz нулевых байтов.Примечания
memmove может использоваться для задания эффективного типа объекта, полученного с помощью функции выделения.
Несмотря на то, что функция специфицирована «как если бы» использовался временный буфер, фактические реализации этой функции не несут избыточных накладных расходов или двойного копирования или дополнительной памяти. Общий подход (glibc и bsd libc) заключается в копировании байтов вперёд с начала буфера, если назначение начинается перед источником, и назад с конца в противном случае, с возвратом к более эффективному memcpy в случае отсутствия перекрытия.
Там, где строгое алиасирование запрещает проверку одной и той же памяти как значений двух разных типов, memmove может использоваться для преобразования значений.
Пример
#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 str[] = "1234567890";
puts(str);
memmove(str+4, str+3, 3); // copy from [4,5,6] to [5,6,7]
puts(str);
// 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};
memmove(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;
memmove(&n, &d, sizeof d); // OK
printf("%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 = memmove_s(dst,sizeof dst,src,5);
printf("dst = \"%s\", r = %d\n", dst,r);
r = memmove_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
}Возможный вывод:
1234567890 1234456890 0x1.999999999999ap-4 is 3fb999999999999a as an int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
Ссылки
- Стандарт C17 (ISO/IEC 9899:2018):
- 7.24.2.2 Функция memmove (с. 264)
- K.3.7.1.2 Функция memmove_s (с. 446)
- Стандарт C11 (ISO/IEC 9899:2011):
- 7.24.2.2 Функция memmove (с. 363)
- K.3.7.1.2 Функция memmove_s (с. 615)
- Стандарт C99 (ISO/IEC 9899:1999):
- 7.21.2.2 Функция memmove (с. 326)
- Стандарт C89/C90 (ISO/IEC 9899:1990):
- 4.11.2.2 Функция memmove
См. также
|
(C11) | копирование одного буфера в другой (функция) |
|
(C95)(C11) | копирование определенного количества широких символов между двумя, возможно, перекрывающимися, массивами (функция) |
Документация C++ для memmove |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/string/byte/memmove