memcpy, memcpy_s
Von cppreference.com
| 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.-
destodersrcist ein Nullzeiger -
destszodercountist größer als RSIZE_MAX -
countist größer alsdestsz(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_snur 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
Führen Sie diesen Code aus
#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
| (C23) |
kopiert einen Puffer in einen anderen und stoppt nach dem angegebenen Trennzeichen (Funktion) |
| (C11) |
verschiebt einen Puffer in einen anderen (Funktion) |
| (C95)(C11) |
kopiert eine bestimmte Anzahl breiter Zeichen zwischen zwei nicht überlappenden Arrays (Funktion) |
| C++-Dokumentation für memcpy
| |