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:
destodersrcist ein Nullzeigerdestszodercountist größer als RSIZE_MAXcountist größer alsdestsz(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
dest2) 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
Diesen Code ausführen
#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
(C23) |
kopiert einen Puffer in einen anderen, stoppt nach dem angegebenen Trennzeichen (Funktion) |
(C11) |
verschiebt einen Puffer in einen anderen (Funktion) |
(C95)(C11) |
kopiert eine bestimmte Anzahl von Breitzeichen zwischen zwei sich nicht überlappenden Arrays (Funktion) |
C++-Dokumentation für memcpy
| |