Namespaces
Variants

memcpy, memcpy_s

From cppreference.net
< c ‎ | string ‎ | byte
Definiert in Header <string.h>
(1)
void * memcpy ( void * dest, const void * src, size_t count ) ;
(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, zum Objekt, auf das dest zeigt. Beide Objekte werden als Arrays von unsigned char interpretiert.
Das Verhalten ist undefiniert, wenn der Zugriff über das Ende des dest -Arrays hinaus erfolgt. Wenn sich die Objekte überlappen (was einen Verstoß gegen den restrict -Vertrag darstellt) (seit C99) , ist das Verhalten undefiniert. Das Verhalten ist undefiniert, wenn entweder dest oder src ein ungültiger oder null-Zeiger ist.
2) Gleich wie (1) , mit der Ausnahme, dass die folgenden Fehler zur Laufzeit erkannt werden und dazu führen, dass der gesamte Zielbereich [ dest, dest + destsz ) ausgelöscht wird (sofern sowohl dest als auch destsz gültig sind), sowie die derzeit installierte constraint handler -Funktion aufgerufen wird:
  • dest oder src ist ein null pointer
  • destsz oder count ist größer als RSIZE_MAX
  • count ist größer als destsz (buffer overflow würde auftreten)
  • die Quell- und Zielobjekte überlappen sich
Das Verhalten ist undefiniert, wenn die Größe des Zeichenarrays, auf das dest zeigt, < count <= destsz ; mit anderen Worten, ein fehlerhafter Wert von destsz macht den drohenden Pufferüberlauf nicht sichtbar.
Wie bei allen grenzprüfenden Funktionen ist memcpy_s nur garantiert verfügbar, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ auf den Integer-Konstantenwert 1 setzt, bevor <string.h> eingebunden wird.

Inhaltsverzeichnis

Parameter

dest - Zeiger auf das zu kopierende Zielobjekt
destsz - maximale Anzahl der Bytes, die im Ziel modifiziert werden sollen (typischerweise die Größe des Zielobjekts)
src - Zeiger auf das zu kopierende Quellobjekt
count - Anzahl der zu kopierenden Bytes

Rückgabewert

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

Hinweise

memcpy kann verwendet werden, um den effektiven Typ eines Objekts festzulegen, das durch eine Allokationsfunktion erhalten wurde.

memcpy ist die schnellste Bibliotheksfunktion für Speicher-zu-Speicher-Kopieren. Sie ist in der Regel effizienter als strcpy , die die zu kopierenden Daten scannen muss, oder memmove , die Vorkehrungen zur Behandlung überlappender Eingaben treffen muss.

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

Wo strict aliasing die Untersuchung desselben Speichers als Werte zweier unterschiedlicher Typen verbietet, kann memcpy zur Konvertierung der Werte verwendet werden.

Beispiel

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    // einfache Verwendung
    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]);
    // Setzen des effektiven Typs des allokierten Speichers auf int
    int *p = malloc(3*sizeof(int));   // allokierter Speicher hat keinen effektiven Typ
    int arr[3] = {1,2,3};
    memcpy(p,arr,3*sizeof(int));      // allokierter Speicher hat nun einen effektiven Typ
    // Neuinterpretation von Daten
    double d = 0.1;
//    int64_t n = *(int64_t*)(&d); // Verletzung des Strict Aliasing
    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 ist größer als 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

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

Siehe auch

(C23)
kopiert einen Puffer in einen anderen und stoppt nach dem angegebenen Trennzeichen
(Funktion)
verschiebt einen Puffer in einen anderen
(Funktion)
kopiert eine bestimmte Anzahl von Breitzeichen zwischen zwei nicht überlappenden Arrays
(Funktion)