memmove, memmove_s
|
Definido en el encabezado
<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) | (desde C11) |
-
- dest o src es un puntero nulo
- destsz o count es mayor que RSIZE_MAX
- count es mayor que destsz (ocurriría un desbordamiento de búfer)
-
Como con todas las funciones con verificación de límites,
memmove_ssolo está garantizada su disponibilidad si __STDC_LIB_EXT1__ está definido por la implementación y si el usuario define __STDC_WANT_LIB_EXT1__ a la constante entera 1 antes de incluir <string.h> .
Contenidos |
Parámetros
| dest | - | puntero al objeto destino de la copia |
| destsz | - | número máximo de bytes a modificar en el destino (normalmente el tamaño del objeto destino) |
| src | - | puntero al objeto fuente de la copia |
| count | - | número de bytes a copiar |
Valor de retorno
Notas
memmove
puede utilizarse para establecer el
tipo efectivo
de un objeto obtenido mediante una función de asignación.
A pesar de estar especificada "como si" se utilizara un búfer temporal, las implementaciones reales de esta función no incurren en la sobrecarga de doble copia o memoria adicional. Un enfoque común (glibc y bsd libc) es copiar bytes hacia adelante desde el inicio del búfer si el destino comienza antes del origen, y hacia atrás desde el final en caso contrario, con una alternativa al más eficiente memcpy cuando no hay superposición alguna.
Donde
strict aliasing
prohíbe examinar la misma memoria como valores de dos tipos diferentes,
memmove
puede utilizarse para convertir los valores.
Ejemplo
#define __STDC_WANT_LIB_EXT1__ 1 #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char str[] = "1234567890"; puts(str); memmove(str + 4, str + 3, 3); // copiar desde [4,5,6] a [5,6,7] puts(str); // estableciendo el tipo efectivo de la memoria asignada como int int* p = malloc(3 * sizeof(int)); // la memoria asignada no tiene tipo efectivo int arr[3] = {1, 2, 3}; memmove(p, arr, 3 * sizeof(int)); // la memoria asignada ahora tiene un tipo efectivo // reinterpretando datos double d = 0.1; // int64_t n = *(int64_t*)(&d); // violación de aliasing estricto int64_t n; memmove(&n, &d, sizeof d); // OK printf("%a es %" PRIx64 " como 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 es mayor que 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 }
Salida posible:
1234567890 1234456890 0x1.999999999999ap-4 es 3fb999999999999a como int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 7.24.2.2 La función memmove (p: TBD)
-
- K.3.7.1.2 La función memmove_s (p: TBD)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 7.24.2.2 La función memmove (p: 264)
-
- K.3.7.1.2 La función memmove_s (p: 446)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 7.24.2.2 La función memmove (p: 363)
-
- K.3.7.1.2 La función memmove_s (p: 615)
- Estándar C99 (ISO/IEC 9899:1999):
-
- 7.21.2.2 La función memmove (p: 326)
- Estándar C89/C90 (ISO/IEC 9899:1990):
-
- 4.11.2.2 La función memmove
Véase también
|
(C11)
|
copia un búfer a otro
(función) |
|
(C95)
(C11)
|
copia cierta cantidad de caracteres anchos entre dos arreglos, posiblemente superpuestos
(función) |
|
C++ documentation
para
memmove
|
|