Namespaces
Variants

memcpy, memcpy_s

Von de.cppreference.net
Definiert in Header <string.h>
void* memcpy( void* dest, const void* src, size_t count );
(1) (bis C99)
void* memcpy( void* restrict dest, const void* restrict src, size_t count );
(seit C99)
errno_t memcpy_s( void* restrict dest, rsize_t destsz,
                  const void* restrict src, rsize_t count );
(2) (seit C11)
1) Kopiert count Zeichen vom Objekt, auf das src zeigt, in das Objekt, auf das dest zeigt. Beide Objekte werden als Arrays von unsigned char interpretiert.
Das Verhalten ist undefiniert, wenn auf Speicher jenseits des Endes des dest Arrays zugegriffen wird. Falls sich die Objekte überlappen (was einen Verstoß gegen die restrict-Vereinbarung darstellt)(seit C99), ist das Verhalten undefiniert. Das Verhalten ist undefiniert, wenn entweder dest oder src ein ungültiger oder Nullzeiger ist.
2) Wie (1), mit der Ausnahme, dass die folgenden Fehler zur Laufzeit erkannt werden und dazu führen, dass der gesamte Zielbereich [dest, dest + destsz) auf null gesetzt wird (falls sowohl dest als auch destsz gültig sind) und dass die derzeit installierte Constraint-HandlerFunktion aufgerufen wird:
  • dest oder src ist ein Nullzeiger
  • destsz oder count ist größer als RSIZE_MAX
  • count ist größer als destsz (Pufferüberlauf würde auftreten)
  • die Quell- und Zielobjekte überlappen sich
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das dest < count < zeigt, = destsz; mit anderen Worten, ein fehlerhafter Wert von destsz deckt den bevorstehenden Pufferüberlauf nicht auf.
Wie bei allen bereichsgeprüften Funktionen ist memcpy_s nur dann garantiert verfügbar, wenn __STDC_LIB_EXT1__ von der Implementierung definiert ist und der Benutzer __STDC_WANT_LIB_EXT1__ als die ganzzahlige Konstante 1 definiert, bevor er <string.h> einbindet.

Parameter

dest - Zeiger auf das Zielobjekt
destsz - maximale Anzahl von Bytes, die im Ziel geändert werden dürfen (typischerweise die Größe des Zielobjekts)
src - Zeiger auf das Quellobjekt
count - Anzahl der zu kopierenden Bytes

Rückgabewert

1) Gibt eine Kopie von dest
2) Gibt bei Erfolg Null und bei Fehler einen Wert ungleich Null zurück. Bei Fehler, falls dest kein Nullzeiger ist und destsz gültig ist, werden destsz Nullbytes in das Zielarray geschrieben.

Anmerkungen

memcpy kann verwendet werden, um den effektiven Typ eines Objekts zu setzen, das von einer Allokationsfunktion erhalten wurde.

memcpy ist die schnellste Bibliotheksroutine für Speicher-zu-Speicher-Kopien. Sie ist normalerweise effizienter als strcpy, das die kopierten Daten scannen muss, oder memmove, das Vorsichtsmaßnahmen zur Behandlung überlappender Eingaben treffen muss.

Mehrere C-Compiler wandeln geeignete Speicherkopierschleifen in memcpy Aufrufe um.

Wo strenges Aliasing das Betrachten desselben Speichers als Werte zweier verschiedener Typen verbietet, kann memcpy verwendet werden, um die Werte zu konvertieren.

Beispiel

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

Mögliche Ausgabe:

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

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 7.24.2.1 Die memcpy-Funktion (p: TBD)
  • K.3.7.1.1 Die memcpy_s-Funktion (p: TBD)
  • C17-Standard (ISO/IEC 9899:2018):
  • 7.24.2.1 Die memcpy-Funktion (p: TBD)
  • K.3.7.1.1 Die memcpy_s-Funktion (p: TBD)
  • C11-Standard (ISO/IEC 9899:2011):
  • 7.24.2.1 Die memcpy-Funktion (p: 362)
  • K.3.7.1.1 Die memcpy_s-Funktion (p: 614)
  • C99-Standard (ISO/IEC 9899:1999):
  • 7.21.2.1 Die memcpy-Funktion (p: 325)
  • C89/C90-Standard (ISO/IEC 9899:1990):
  • 4.11.2.1 Die memcpy-Funktion

Siehe auch

kopiert einen Puffer in einen anderen, stoppt nach dem angegebenen Trennzeichen
(Funktion)
verschiebt einen Puffer in einen anderen
(Funktion)
kopiert eine bestimmte Anzahl von Breitzeichen zwischen zwei sich nicht überlappenden Arrays
(Funktion)
C++-Dokumentation für memcpy