memcpy, memcpy_s
De es.cppreference.net
| Definido en el encabezado <string.h>
|
||
void* memcpy( void* dest, const void* src, size_t count );
|
(1) | (hasta C99) |
void* memcpy( void* restrict dest, const void* restrict src, size_t count );
|
(desde C99) | |
errno_t memcpy_s( void* restrict dest, rsize_t destsz,
const void* restrict src, rsize_t count );
|
(2) | (desde C11) |
1) Copia
count caracteres del objeto apuntado por src al objeto apuntado por dest. Ambos objetos se interpretan como arreglos de unsigned char. El comportamiento es indefinido si se accede más allá del final del
dest arreglo. Si los objetos se superponen (lo cual es una violación del restrict contrato)(desde C99), el comportamiento es indefinido. El comportamiento es indefinido si dest o src es un puntero nulo o inválido.2) Igual que (1), excepto que los siguientes errores se detectan en tiempo de ejecución y causan que todo el rango de destino
[dest, dest + destsz) sea puesto a cero (si tanto dest como destsz son válidos), así como llamar a la función manejador de restricciones actualmente instalada:
destosrces un puntero nulodestszocountes mayor que RSIZE_MAXcountes mayor quedestsz(se produciría un desbordamiento de búfer)- los objetos de origen y destino se superponen
El comportamiento es indefinido si el tamaño del arreglo de caracteres apuntado por
dest < count <= destsz; en otras palabras, un valor erróneo de destsz no expone el inminente desbordamiento de búfer. Como con todas las funciones con verificación de límites,
memcpy_s solo se garantiza que esté disponible 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>.Parámetros
| dest | - | puntero al objeto de destino |
| destsz | - | número máximo de bytes a modificar en el destino (típicamente el tamaño del objeto de destino) |
| src | - | puntero al objeto de origen |
| count | - | número de bytes a copiar |
Valor de retorno
1) Devuelve una copia de
dest2) Devuelve cero en éxito y un valor distinto de cero en error. Además, en caso de error, si
dest no es un puntero nulo y destsz es válido, escribe destsz bytes cero en el arreglo de destino.Notas
memcpy puede usarse para establecer el tipo efectivo de un objeto obtenido mediante una función de asignación.
memcpy es la rutina de biblioteca más rápida para copia de memoria a memoria. Generalmente es más eficiente que strcpy, que debe escanear los datos que copia o memmove, que debe tomar precauciones para manejar entradas superpuestas.
Varios compiladores de C transforman bucles adecuados de copia de memoria en memcpy llamadas.
Donde aliasing estricto prohíbe examinar la misma memoria como valores de dos tipos diferentes, memcpy puede usarse para convertir los valores.
Ejemplo
Ejecutar este código
#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
}
Posible salida:
once
0x1.999999999999ap-4 is 3fb999999999999a as an 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.1 La función memcpy (p: TBD)
- K.3.7.1.1 La función memcpy_s (p: TBD)
- Estándar C17 (ISO/IEC 9899:2018):
- 7.24.2.1 La función memcpy (p: TBD)
- K.3.7.1.1 La función memcpy_s (p: TBD)
- Estándar C11 (ISO/IEC 9899:2011):
- 7.24.2.1 La función memcpy (p: 362)
- K.3.7.1.1 La función memcpy_s (p: 614)
- Estándar C99 (ISO/IEC 9899:1999):
- 7.21.2.1 La función memcpy (p: 325)
- Estándar C89/C90 (ISO/IEC 9899:1990):
- 4.11.2.1 La función memcpy
Véase también
(C23) |
copia un búfer a otro, deteniéndose después del delimitador especificado (función) |
(C11) |
mueve un búfer a otro (función) |
(C95)(C11) |
copia una cierta cantidad de caracteres anchos entre dos arreglos no superpuestos (función) |
Documentación de C++ para memcpy
| |