Namensräume
Varianten
Aktionen

memcpy, memcpy_s

Von cppreference.com
< 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 aus dem durch src dargestellten Objekt in das durch dest dargestellte Objekt. 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 überschneiden (was eine Verletzung des restrict-Vertrags darstellt)(seit C99), ist das Verhalten undefiniert. Das Verhalten ist undefiniert, wenn dest oder src ein ungültiger Zeiger oder ein Nullzeiger ist.
2) Wie (1), außer dass die folgenden Fehler zur Laufzeit erkannt werden und dazu führen, dass der gesamte Zielbereich [dest, dest+destsz) auf Null gesetzt wird (wenn sowohl dest als auch destsz gültig sind) und die aktuell installierte Constraint-Handler-Funktion 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 die Zielobjekte überschneiden sich
Das Verhalten ist undefiniert, wenn die Größe des durch dest dargestellten Zeichenarrays < count <= destsz ist; mit anderen Worten, ein fehlerhafter Wert von destsz deckt den drohenden Pufferüberlauf nicht auf.
Wie bei allen grenzgeprüften Funktionen ist memcpy_s nur dann garantiert verfügbar, wenn __STDC_LIB_EXT1__ von der Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ vor dem Einbinden von <string.h> auf die Ganzzahlkonstante 1 setzt.

Inhalt

[bearbeiten] Parameter

dest - Zeiger auf das zu kopierende Objekt
destsz - maximale Anzahl von Bytes, die im Ziel modifiziert werden sollen (typischerweise die Größe des Zielobjekts)
src - Zeiger auf das zu kopierende Objekt
zählt - Anzahl der zu kopierenden Bytes

[bearbeiten] Rückgabewert

1) Gibt eine Kopie von dest zurück.
2) Gibt im Erfolgsfall Null und im Fehlerfall einen Wert ungleich Null zurück. Bei einem Fehler wird außerdem, wenn dest kein Nullzeiger ist und destsz gültig ist, destsz Null-Bytes in das Zielarray geschrieben.

[bearbeiten] Hinweise

memcpy kann verwendet werden, um den effektiven Typ eines von einer Allokationsfunktion erhaltenen Objekts festzulegen.

memcpy ist die schnellste Bibliotheksroutine für Speicher-zu-Speicher-Kopien. Sie ist in der Regel effizienter als strcpy, das die kopierten Daten scannen muss, oder memmove, das Vorsichtsmaßnahmen treffen muss, um überlappende Eingaben zu behandeln.

Mehrere C-Compiler wandeln geeignete Speicher-Kopier-Schleifen in memcpy-Aufrufe um.

Wo Strict Aliasing die Untersuchung desselben Speichers als Werte zweier unterschiedlicher Typen verbietet, kann memcpy zur Konvertierung von Werten verwendet werden.

[bearbeiten] 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)
{
    // 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

[bearbeiten] Referenzen

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

[bearbeiten] Siehe auch

kopiert einen Puffer in einen anderen und stoppt nach dem angegebenen Trennzeichen
(Funktion) [bearbeiten]
verschiebt einen Puffer in einen anderen
(Funktion) [bearbeiten]
kopiert eine bestimmte Anzahl breiter Zeichen zwischen zwei nicht überlappenden Arrays
(Funktion) [bearbeiten]
C++-Dokumentation für memcpy