Namespaces
Variants

memcpy, memcpy_s

De fr.cppreference.net
Défini dans l'en-tête <string.h>
void* memcpy( void* dest, const void* src, size_t count );
(1) (jusqu'à C99)
void* memcpy( void* restrict dest, const void* restrict src, size_t count );
(depuis C99)
errno_t memcpy_s( void* restrict dest, rsize_t destsz,
                  const void* restrict src, rsize_t count );
(2) (depuis C11)
1) Copie count caractères de l'objet pointé par src vers l'objet pointé par dest. Les deux objets sont interprétés comme des tableaux de unsigned char.
Le comportement est indéfini si l'accès se produit au-delà de la fin du tableau dest. Si les objets se chevauchent (ce qui est une violation du contrat restrict)(depuis C99), le comportement est indéfini. Le comportement est indéfini si dest ou src est un pointeur invalide ou nul.
2) Identique à (1), sauf que les erreurs suivantes sont détectées à l'exécution et provoquent la mise à zéro de toute la plage de destination [dest, dest + destsz) (si dest et destsz sont valides), ainsi que l'appel de la fonction gestionnaire de contrainte actuellement installée :
  • dest ou src est un pointeur nul
  • destsz ou count est supérieur à RSIZE_MAX
  • count est supérieur à destsz (un débordement de tampon se produirait)
  • les objets source et destination se chevauchent
Le comportement est indéfini si la taille du tableau de caractères pointé par dest < count <= destsz ; en d'autres termes, une valeur erronée de destsz n'expose pas le débordement de tampon imminent.
Comme pour toutes les fonctions avec vérification des limites, memcpy_s n'est garantie d'être disponible que si __STDC_LIB_EXT1__ est définie par l'implémentation et si l'utilisateur définit __STDC_WANT_LIB_EXT1__ à la constante entière 1 avant d'inclure <string.h>.

Paramètres

dest - pointeur vers l'objet à copier vers
destsz - nombre maximal d'octets à modifier dans la destination (généralement la taille de l'objet de destination)
src - pointeur vers l'objet à copier depuis
count - nombre d'octets à copier

Valeur de retour

1) Renvoie une copie de dest
2) Renvoie zéro en cas de succès et une valeur non nulle en cas d'erreur. En cas d'erreur, si dest n'est pas un pointeur nul et destsz est valide, écrit destsz octets de zéro dans le tableau de destination.

Notes

memcpy peut être utilisé pour définir le type effectif d'un objet obtenu par une fonction d'allocation.

memcpy est la routine de bibliothèque la plus rapide pour la copie mémoire à mémoire. Elle est généralement plus efficace que strcpy, qui doit analyser les données qu'elle copie, ou memmove, qui doit prendre des précautions pour gérer les entrées qui se chevauchent.

Plusieurs compilateurs C transforment les boucles de copie mémoire appropriées en appels à memcpy.

Lorsque l'aliasing strict interdit d'examiner la même mémoire en tant que valeurs de deux types différents, memcpy peut être utilisé pour convertir les valeurs.

Exemple

#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
}

Sortie possible :

once
0x1.999999999999ap-4 is 3fb999999999999a as an int64_t
dst = "aaaaayxyxy", r = 0
dst = "\0\0\0\0\0yxyxy", r = 22

Références

  • Norme C23 (ISO/IEC 9899:2024) :
  • 7.24.2.1 La fonction memcpy (p. : à déterminer)
  • K.3.7.1.1 La fonction memcpy_s (p. : à déterminer)
  • Norme C17 (ISO/IEC 9899:2018) :
  • 7.24.2.1 La fonction memcpy (p. : à déterminer)
  • K.3.7.1.1 La fonction memcpy_s (p. : à déterminer)
  • Norme C11 (ISO/IEC 9899:2011) :
  • 7.24.2.1 La fonction memcpy (p. : 362)
  • K.3.7.1.1 La fonction memcpy_s (p. : 614)
  • Norme C99 (ISO/IEC 9899:1999) :
  • 7.21.2.1 La fonction memcpy (p. : 325)
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 4.11.2.1 La fonction memcpy

Voir aussi

copie un tampon vers un autre, en s'arrêtant après le délimiteur spécifié
(fonction)
déplace un tampon vers un autre
(fonction)
copie une certaine quantité de caractères larges entre deux tableaux non chevauchants
(fonction)
Documentation C++ pour memcpy