ProgramaciónDesarrollador Backend C

¿Cómo implementar una copia de memoria segura entre arrays en C? ¿Qué funciones de la biblioteca estándar usar y en qué se diferencian?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

Historia de la pregunta

La copia de memoria segura es una de las tareas más comunes y críticas en C. Inicialmente, los programas usaban un ciclo para copiar byte a byte. Más tarde se añadieron funciones estándar: memcpy, memmove, así como alternativas más seguras como strncpy para cadenas. Una copia incorrecta puede llevar a desbordamientos de búfer y vulnerabilidades.

Problema

El uso de una función inadecuada o un tamaño incorrecto al copiar puede dañar los datos o incluso abrir caminos a partes interesadas en la seguridad. Distinguir cuándo usar memmove y cuándo es aceptable memcpy es crucial para evitar errores con áreas de memoria superpuestas.

Solución

Para copiar de manera segura memoria no relacionada con cadenas, use:

memcpy(dest, src, n);
  • memcpy copia rápidamente n bytes de src a dest si sus áreas de memoria no se superponen.
  • Si las áreas pueden superponerse, use memmove:
memmove(dest, src, n);

Para copiar cadenas, use ya sea strncpy o, preferiblemente, alternativas modernas y seguras si están disponibles (strlcpy).

Características clave:

  • memcpy es seguro solo en ausencia de superposición entre src y dest.
  • memmove funciona correctamente incluso con áreas de memoria superpuestas.
  • Para cadenas, es mejor usar funciones especializadas, considerando el terminador nulo.

Preguntas engañosas.

1. ¿Cuál es la diferencia entre memcpy y memmove y cuándo se necesita cada función?

memcpy funciona muy rápido, pero no está destinado para áreas de memoria que se superponen; el resultado será impredecible. memmove garantiza una copia correcta sin importar la superposición:

int arr[] = {1,2,3,4,5}; // memmove: copiamos de forma segura con superposición memmove(arr+1, arr, 4 * sizeof(int));

2. ¿Es seguro usar strcpy para copiar una cadena en un búfer más pequeño?

No, la función strcpy no verifica el tamaño del búfer de destino. Esto a menudo resulta en desbordamiento de búfer. Es mejor usar strncpy, o strlcpy (si está disponible), o controlar explícitamente el tamaño:

char dest[5]; strncpy(dest, src, sizeof(dest)-1); // src debe ser más corto que 5 caracteres

3. ¿Se puede usar memcpy para copiar estructuras con punteros?

Sí, pero esto solo copia los punteros en sí, no los datos en esas direcciones. Esto puede llevar a errores al trabajar con memoria y liberaciones dobles.

Errores comunes y anti-patrones

  • Usar memcpy con superposición de áreas de memoria.
  • Ignorar el tamaño del búfer de destino.
  • Copiar estructuras que contienen punteros con memcpy simple (copia superficial).

Ejemplo de la vida real

Caso negativo

Se copia una cadena larga en un búfer pequeño usando strcpy sin verificar la longitud de la fuente. Ocurre un desbordamiento de búfer, lo que conduce a una vulnerabilidad.

Ventajas:

  • Código mínimo, ejecución rápida.

Desventajas:

  • Vulnerabilidad de seguridad, posibles cierres inesperados, corrupción de memoria.

Caso positivo

Se utiliza strncpy o memmove con control preciso del tamaño, garantizando manualmente el carácter nulo de finalización de la cadena.

Ventajas:

  • Comportamiento predecible, protección contra desbordamientos de búfer.

Desventajas:

  • Requiere control adicional sobre la longitud y, posiblemente, una ligera reducción de la velocidad debido a las comprobaciones adicionales.