jueves, 18 de agosto de 2011

Las Funciones memcpy() Y memmove()

Cuando terminamos el ciclo básico y dominamos una buena parte de las funciones de entrada y salida, empezamos a sentirnos agobiados por la incapacidad de mover y copiar la información que obtenemos. Quisiéramos o no, nos vemos forzados a estudiar las funciones para la manipulación de caracteres.

La  función strcpy es la que primero hallamos y utilizamos hasta que vemos su peligro, luego es strncpy, mas prometedora que strcpy pero el peligro aun toca la puerta, y al igual que strcpy solo funciona con cadena de caracteres y corrompen los datos al agregar el carácter \0 al final (con strncpy no siempre es cierto).

Buscando hallamos a memcpy() y memmove() e inmediatamente caemos en una encrucijada ¿Cuándo debo usar memmove? De esto se trata este artículo, explicar cuando utilizarlas y porque.
/* Tomado del código fuente de linux */
void *memcpy(void *dest, const void *src, size_t count)
{
 char       *tmp = dest;
 const char *s   = src;

 while(count--)
  *tmp++ = *s++;
 return dest;
}
Debido a la gran cantidad de versiones y optimizaciones realizadas a esta función, copie esta implementación para la cual su comportamiento está definido en todas las arquitecturas (no intentes optimizarla con el compilador). Antes de entrar en lleno, examinemos que dicen las especificaciones de ambas funciones con el Traductor 9000:


Todo parece estar bien, a excepción de esa palabra; superposición. Para entender más un poco sobre la superposición entre dos áreas de memoria, veamos un ejemplo visual sin superposición, pero antes definamos (de manera vaga) lo que superposición significa (para nuestros fines).
Es cuando dos áreas de memorias están correlacionadas y una modificación en una de las partes se ve reflejada a lo largo de las modificaciones siguientes.

Como se puede apreciar en la animación, una modificación en una área de memoria no afecta las modificaciones sucesivas. Veamos ahora otra animación un ejemplo que muestra claramente la superposición.

En la animación anterior, el uso de la función memmove es necesario. A estas alturas te podrías estar empezando a preguntar si  utilizar memmove y nunca memcpy, la respuesta simple es: podría. Los tíos de FreeBSD (quizás otros) meditaron sobre esto y modificaron su API, de manera que cuanto intentes utilizar memcpy o memmove, sin darte cuenta estarás usando bcopy; función muy parecida a memmove.

Despedida

Luego de haber leído este artículo sería lógico si terminas preguntándote ¿Cuál es el propósito de la función memcpy? ¿Introducir posibles errores en nuestra aplicaciones o copiar áreas de memoria? La respuesta es que memcpy algunas veces posee optimizaciones específicas; es más rápida.

Ahora que conocemos la diferencia entre ambas funciones usarémos memmove solo cuando sea necesario; siempre tratemos de utilizar memcpy, la cual en muchos casos posee mayor rendimiento.

Comentarios y Cosas Raras
 ... os he atrapado con las manos en la falda ¡Qué problema! ¿Eh? Terroríficas, precisas y calculadoras (frías), no podemos escapar de ellas; nos tienen dominados ...
Enlaces
  1. Ejemplo sin superposición
  2. Ejemplo con superposición
  3. Ejemplo con memmove

1 comentario:

  1. Soy estudiante de programación, tuve horas dandole vueltas a esta función y su diferencia, esta es la mejor explicación que creo poder encontrar, entendí a la perfección, gracias.

    ResponderEliminar