memmove, memmove_s
|
Definiert in Header
<string.h>
|
||
|
void
*
memmove
(
void
*
dest,
const
void
*
src,
size_t
count
)
;
|
(1) | |
|
errno_t memmove_s
(
void
*
dest, rsize_t destsz,
const
void
*
src, rsize_t count
)
;
|
(2) | (seit C11) |
-
- dest oder src ist ein Nullzeiger
- destsz oder count ist größer als RSIZE_MAX
- count ist größer als destsz (ein Pufferüberlauf würde auftreten)
-
Wie bei allen grenzprüfenden Funktionen ist
memmove_snur garantiert verfügbar, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und wenn der Benutzer __STDC_WANT_LIB_EXT1__ auf den ganzzahligen 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
Hinweise
memmove
kann verwendet werden, um den
effective type
eines Objekts festzulegen, das durch eine Allokationsfunktion erhalten wurde.
Obwohl spezifiziert "als ob" ein temporärer Puffer verwendet würde, verursachen tatsächliche Implementierungen dieser Funktion weder den Overhead noch doppeltes Kopieren oder zusätzlichen Speicher. Ein gängiger Ansatz (glibc und bsd libc) ist, Bytes vorwärts vom Anfang des Puffers zu kopieren, wenn das Ziel vor der Quelle beginnt, und rückwärts vom Ende andernfalls, mit einem Fallback auf das effizientere memcpy wenn es überhaupt keine Überlappung gibt.
Wo
strict aliasing
die Untersuchung desselben Speichers als Werte von zwei verschiedenen Typen verbietet,
kann
memmove
zur Konvertierung der Werte verwendet werden.
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) { char str[] = "1234567890"; puts(str); memmove(str + 4, str + 3, 3); // kopiere von [4,5,6] nach [5,6,7] puts(str); // Setze den effektiven Typ des allokierten Speichers auf int int* p = malloc(3 * sizeof(int)); // allokierter Speicher hat keinen effektiven Typ int arr[3] = {1, 2, 3}; memmove(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; memmove(&n, &d, sizeof d); // OK printf("%a ist %" PRIx64 " als int64_t\n", d, n); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char src[] = "aaaaaaaaaa"; char dst[] = "xyxyxyxyxy"; int r = memmove_s(dst, sizeof dst, src, 5); printf("dst = \"%s\", r = %d\n", dst, r); r = memmove_s(dst, 5, src, 10); // Anzahl 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:
1234567890 1234456890 0x1.999999999999ap-4 ist 3fb999999999999a als int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 7.24.2.2 Die memmove-Funktion (S.: TBD)
-
- K.3.7.1.2 Die memmove_s-Funktion (S.: TBD)
- C17-Standard (ISO/IEC 9899:2018):
-
- 7.24.2.2 Die memmove-Funktion (S. 264)
-
- K.3.7.1.2 Die memmove_s-Funktion (S. 446)
- C11-Standard (ISO/IEC 9899:2011):
-
- 7.24.2.2 Die memmove-Funktion (S: 363)
-
- K.3.7.1.2 Die memmove_s-Funktion (S: 615)
- C99-Standard (ISO/IEC 9899:1999):
-
- 7.21.2.2 Die memmove-Funktion (S. 326)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 4.11.2.2 Die memmove-Funktion
Siehe auch
|
(C11)
|
kopiert einen Puffer in einen anderen
(Funktion) |
|
(C95)
(C11)
|
kopiert eine bestimmte Anzahl von Breitzeichen zwischen zwei, möglicherweise überlappenden, Arrays
(Funktion) |
|
C++-Dokumentation
für
memmove
|
|