4.a Memcpy, memmove y memcmp
memcpy
, memmove
y memcmp
son funciones en el lenguaje de programación C que trabajan con memoria y se utilizan para realizar diferentes operaciones relacionadas con arreglos de bytes. Aquí tienes una breve descripción de cada una:
memcpy
(Memory Copy):- Uso:
void *memcpy(void *dest, const void *src, size_t n);
- Descripción:
memcpy
se utiliza para copiar un bloque de memoria desde una ubicación de origen (src
) a una ubicación de destino (dest
) en la memoria. Copia un número específico de bytes (n
) desde la ubicación de origen a la ubicación de destino. - Importante:
memcpy
no verifica si las áreas de memoria de origen y destino se superponen. Por lo tanto, si las áreas de memoria se superponen, el comportamiento es indefinido.
- Uso:
memmove
(Memory Move):- Uso:
void *memmove(void *dest, const void *src, size_t n);
- Descripción:
memmove
se utiliza para copiar un bloque de memoria desde una ubicación de origen (src
) a una ubicación de destino (dest
) en la memoria, similar amemcpy
. La diferencia principal es quememmove
garantiza que los datos se copiarán correctamente incluso si las áreas de memoria de origen y destino se superponen. Esto lo hace más seguro cuando trabajas con datos superpuestos. - Importante:
memmove
puede ser un poco más lento quememcpy
debido a la necesidad de manejar la superposición de memoria.
- Uso:
memcmp
(Memory Compare):- Uso:
int memcmp(const void *s1, const void *s2, size_t n);
- Descripción:
memcmp
se utiliza para comparar dos bloques de memoria (s1
ys2
) de igual longitud (n
) byte a byte. Devuelve un valor entero que indica si los bloques son iguales, y si no lo son, cuál es mayor o menor en función de la comparación de bytes. - Valor de retorno: Devuelve un valor negativo si
s1
es menor ques2
, cero si son iguales y un valor positivo sis1
es mayor ques2
.
- Uso:
Estas tres funciones son muy útiles cuando trabajas con manipulación de memoria en C, pero es importante usarlas de manera segura y considerar las implicaciones de rendimiento y comportamiento en caso de superposición de memoria, especialmente al elegir entre memcpy
y memmove
.
Función memcpy ANSI C
void *memcpy(void *s1, const void *s2, size_t n);
Copia los primeros n caracteres del objeto apuntado por s2 al objeto apuntado por s1.
Valor de retorno:
La función retorna el valor de s1. Si al copiar un objeto al otro se superponen, entonces
el comportamiento no está definido.
#include <stdio.h> #include <string.h> int main() { char a[7] = "abcdefg"; char *ptr; int i; memcpy( ptr, a, 5 ); for( i=0; i<7; i++ ) printf( "a[%d]=%c ", i, a[i] ); printf( "\n" ); for( i=0; i<5; i++ ) printf( "ptr[%d]=%c ", i, ptr[i] ); printf( "\n" ); return 0; }
Yo puedo crear una estructura y hacer una copia de un solo registro como el siguiente ejemplo:
#include <stdio.h> #include <string.h> typedef struct{ int numero; char nombre[20]; }Presidente; int main() { Presidente presi[]={ {1,"De La Rua"}, {2,"Nestor Kirchner"}, {3,"Cristina Fernandez"}, {4,"Mauricio Macri"} }; Presidente copia; memcpy( &copia, &presi[0], sizeof(Presidente) ); printf( "Presidente: %s\n", copia.nombre ); return 0; }
O puedo copiar mas de un registro:
#include <stdio.h> #include <string.h> typedef struct{ int numero; char nombre[20]; }Presidente; int main() { Presidente presi[]={ {1,"De La Rua"}, {2,"Nestor Kirchner"}, {3,"Cristina Fernandez"}, {4,"Mauricio Macri"} }; Presidente copia[4]; memcpy( &copia[0], &presi[0], sizeof(Presidente)*4 ); // copia o presi podria haber mandado for (int i=0; i<4; i++) printf( "Presidente: %s\n", copia[i].nombre ); return 0; }
Función memmove ANSI C
void *memmove(void *s1, const void *s2, size_t n);
Copia los primeros n caracteres del objeto apuntado por s2 al objeto apuntado por
s1.Sin embargo, se asegura de que no estén superpuestos. Por esta razón, copia los
caracteres a un array/arreglo temporalmente. Después vuelve a copiar del array
temporal al objeto en cuestión
Valor de retorno:
La función retorna el valor de s1.
#include <stdio.h> #include <string.h> int main() { char a[7] = "abcdefg"; char *ptr; int i; memmove( ptr, a, 5 ); for( i=0; i<7; i++ ) printf( "a[%d]=%c ", i, a[i] ); printf( "\n" ); for( i=0; i<5; i++ ) printf( "ptr[%d]=%c ", i, ptr[i] ); printf( "\n" ); return 0; }
int main() { int vec[]={1,2,3,4,5}; int vec2[5]; memmove(vec, vec+2,sizeof(int)*3); for (int i=0; i<5; i++) printf( "%d \n", vec[i] ); return 0; }
Otro Ejemplo:
#include <stdio.h> #include <string.h> int main() { char str[] = "Hola, Mundo!"; // Mueve los primeros 5 caracteres al final de la cadena memmove(str + 10, str, 5); printf("Cadena modificada: %s\n", str); return 0; }
En este ejemplo, estamos moviendo los primeros 5 caracteres de la cadena "Hola, Mundo!"
al final de la misma utilizando memmove
. Esto funciona de manera segura incluso cuando los bloques de memoria se superponen.
Función memcmp ANSI C
int memcmp(const void *s1, const void *s2, size_t n);
Compara los primeros n caracteres del objeto apuntado por s1 (interpretado como
unsigned char) con los primeros n caracteres del objeto apuntado por s2 (interpretado
como unsigned char).
Valor de retorno:
La función retorna un número entero mayor, igual, o menor que cero, apropiadamente
según el objeto apuntado por s1 es mayor, igual, o menor que el objeto apuntado por
s2.
#include <stdio.h> #include <string.h> int main() { char a[3] = { 82, 81, 84 }; char b[3] = { 85, 83, 86 }; int i; for( i=0; i<3; i++ ) printf( "a[%d]=%c ", i, a[i] ); printf( "\n" ); for( i=0; i<3; i++ ) printf( "b[%d]=%c ", i, b[i] ); printf( "\n" ); i = memcmp( a, b, 4 ); printf( "a es " ); if( i < 0 ) printf( "menor que" ); else if( i > 0 ) printf( "mayor que" ); else printf( "igual a" ); printf( " b\n" ); return 0; }
Otro Ejemplo:
#include <stdio.h> #include <string.h> int main() { char str1[] = "Hola"; char str2[] = "Hola"; char str3[] = "Holi"; int result1 = memcmp(str1, str2, strlen(str1)); int result2 = memcmp(str1, str3, strlen(str1)); if (result1 == 0) { printf("str1 es igual a str2\n"); } else { printf("str1 no es igual a str2\n"); } if (result2 == 0) { printf("str1 es igual a str3\n"); } else { printf("str1 no es igual a str3\n"); } return 0; }
En este ejemplo, estamos utilizando memcmp
para comparar las cadenas str1
, str2
y str3
. Devuelve 0 si las cadenas son iguales en longitud y contenido, y un valor diferente de 0 si son diferentes. En este caso, str1
es igual a str2
, pero no es igual a str3
.