La fonction memcpy de la bibliothèque standard (string.h) est destinée à la copie octet par octet d'une zone de mémoire d'un endroit à un autre. C'est un outil universel pour copier des tableaux, des structures et d'autres blocs de données lorsque la performance est importante et qu'aucune conversion de type n'est nécessaire.
Historique de la question :
memcpy est apparu avec la première implémentation de la bibliothèque standard, lorsque le besoin de traiter des blocs de mémoire « bruts » s'est fait sentir, par exemple, pour travailler avec des fichiers, des paquets réseau, la sérialisation de données. Des fonctions similaires existent dans presque tous les langages de bas niveau.
Problème :
memcpy ne traite que des octets, elle ne se soucie pas des types de données, de l'alignement, ou de la superposition des zones de mémoire. Des erreurs dans la taille spécifiée ou des zones incorrectes peuvent entraîner des corruptions de mémoire ou des résultats inattendus. De plus, l'utilisation de memcpy pour des zones superposées entraîne un comportement indéfini.
Solution :
Utilisez memcpy uniquement si vous êtes sûr :
memmove.Exemple de code :
#include <string.h> typedef struct { int id; float value; } Item; Item src = {42, 3.14f}; Item dest; memcpy(&dest, &src, sizeof(Item)); // copie la structure octet par octet
Caractéristiques clés :
Peut-on utiliser memcpy pour copier des chaînes (char) ?*
Oui, seulement si la longueur est exactement connue. Si la chaîne est null-terminated, on utilise souvent strcpy ou strncpy. Si la taille est mélangée, un dépassement de mémoire ou une perte du zéro de fin est possible.
char src[] = "abc"; char dest[4]; memcpy(dest, src, 4); // 3 lettres + '\0' sont copiées
Que se passe-t-il lors de la copie de structures avec un alignement non standard ou des pointeurs via memcpy ?
memcpy ne tient compte ni de la sémantique ni des pointeurs internes. Si une structure contient des champs dynamiques (par exemple, char *buf;), seule l'adresse est copiée, et non le contenu. Cela entraîne un « copier superficiel ».
typedef struct { char *buf; } Wrapper; Wrapper src = {malloc(10)}; Wrapper dest; memcpy(&dest, &src, sizeof(Wrapper)); // Seulement le champ pointeur, pas le contenu
Que se passera-t-il si src et dest se chevauchent dans memcpy ?
Le comportement n'est pas défini par la norme, une perte de données peut survenir. Pour une copie avec chevauchement, utilisez memmove :
memmove(dest, src, size); // garantit une copie correcte
Les tableaux se chevauchent : memcpy est utilisé pour déplacer une partie du tableau vers la droite, src et dest se chevauchent partiellement.
Avantages :
Inconvénients :
memmove est utilisé pour traiter des zones se chevauchant, le volume de données est clairement calculé en tant que nombre d'octets dans la structure source.
Avantages :
Inconvénients :