memmove, memmove_s
|
Défini dans l'en-tête
<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) | (depuis C11) |
-
- dest ou src est un pointeur nul
- destsz ou count est supérieur à RSIZE_MAX
- count est supérieur à destsz (un dépassement de tampon se produirait)
-
Comme pour toutes les fonctions à vérification de limites,
memmove_sn'est garantie d'être disponible que si __STDC_LIB_EXT1__ est défini par l'implémentation et si l'utilisateur définit __STDC_WANT_LIB_EXT1__ à la constante entière 1 avant d'inclure <string.h> .
Table des matières |
Paramètres
| dest | - | pointeur vers l'objet de destination de la copie |
| destsz | - | nombre maximal d'octets à modifier dans la destination (généralement la taille de l'objet de destination) |
| src | - | pointeur vers l'objet source de la copie |
| count | - | nombre d'octets à copier |
Valeur de retour
Notes
memmove
peut être utilisé pour définir le
type effectif
d'un objet obtenu par une fonction d'allocation.
Bien que spécifiée "comme si" un tampon temporaire était utilisé, les implémentations réelles de cette fonction n'entraînent pas la surcharge de la double copie ou de la mémoire supplémentaire. Une approche courante (glibc et bsd libc) consiste à copier les octets vers l'avant depuis le début du tampon si la destination commence avant la source, et vers l'arrière depuis la fin sinon, avec un recours à la fonction plus efficace memcpy lorsqu'il n'y a aucun chevauchement.
Lorsque
l'aliasing strict
interdit d'examiner la même mémoire comme des valeurs de deux types différents,
memmove
peut être utilisé pour convertir les valeurs.
Exemple
#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); // copier de [4,5,6] vers [5,6,7] puts(str); // définition du type effectif de la mémoire allouée comme int int* p = malloc(3 * sizeof(int)); // la mémoire allouée n'a pas de type effectif int arr[3] = {1, 2, 3}; memmove(p, arr, 3 * sizeof(int)); // la mémoire allouée a maintenant un type effectif // réinterprétation des données double d = 0.1; // int64_t n = *(int64_t*)(&d); // violation de l'aliasing strict int64_t n; memmove(&n, &d, sizeof d); // OK printf("%a est %" PRIx64 " comme 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); // count est supérieur à 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 }
Sortie possible :
1234567890 1234456890 0x1.999999999999ap-4 est 3fb999999999999a comme int64_t dst = "aaaaayxyxy", r = 0 dst = "\0\0\0\0\0yxyxy", r = 22
Références
- Norme C23 (ISO/CEI 9899:2024) :
-
- 7.24.2.2 La fonction memmove (p: TBD)
-
- K.3.7.1.2 La fonction memmove_s (p: TBD)
- Norme C17 (ISO/CEI 9899:2018) :
-
- 7.24.2.2 La fonction memmove (p: 264)
-
- K.3.7.1.2 La fonction memmove_s (p: 446)
- Norme C11 (ISO/CEI 9899:2011) :
-
- 7.24.2.2 La fonction memmove (p: 363)
-
- K.3.7.1.2 La fonction memmove_s (p: 615)
- Norme C99 (ISO/CEI 9899:1999) :
-
- 7.21.2.2 La fonction memmove (p. 326)
- Norme C89/C90 (ISO/IEC 9899:1990) :
-
- 4.11.2.2 La fonction memmove
Voir aussi
|
(C11)
|
copie un tampon vers un autre
(fonction) |
|
(C95)
(C11)
|
copie une certaine quantité de caractères larges entre deux tableaux, potentiellement chevauchants
(fonction) |
|
Documentation C++
pour
memmove
|
|