Namespaces
Variants

memset, memset_explicit, memset_s

From cppreference.net
< c ‎ | string ‎ | byte
Défini dans l'en-tête <string.h>
void * memset ( void * dest, int ch, size_t count ) ;
(1)
void * memset_explicit ( void * dest, int ch, size_t count ) ;
(2) (depuis C23)
errno_t memset_s ( void * dest, rsize_t destsz, int ch, rsize_t count ) ;
(3) (depuis C11)
1) Copie la valeur ( unsigned char ) ch dans chacun des premiers count caractères de l'objet pointé par dest .
Le comportement est indéfini si l'accès se produit au-delà de la fin du tableau dest. Le comportement est indéfini si dest est un pointeur nul.
2) Identique à (1) , sauf que c'est sécurisé pour les informations sensibles.
3) Identique à (1) , sauf que les erreurs suivantes sont détectées à l'exécution et appellent la fonction gestionnaire de contraintes actuellement installée après avoir stocké ch dans chaque emplacement de la plage de destination [ dest, dest + destsz ) si dest et destsz sont eux-mêmes valides :
  • dest est un pointeur nul
  • destsz ou count est supérieur à RSIZE_MAX
  • count est supérieur à destsz (un dépassement de tampon se produirait)
Le comportement est indéfini si la taille du tableau de caractères pointé par dest < count <= destsz ; en d'autres termes, une valeur erronée de destsz n'expose pas le dépassement de tampon imminent.
Comme pour toutes les fonctions à vérification de limites, memset_s n'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 à remplir
ch - octet de remplissage
count - nombre d'octets à remplir
destsz - taille du tableau de destination

Valeur de retour

1,2) Une copie de dest
3) zéro en cas de succès, non-zéro en cas d'erreur. En cas d'erreur, si dest n'est pas un pointeur nul et que destsz est valide, écrit destsz octets de remplissage ch dans le tableau de destination.

Notes

memset peut être optimisé (selon les règles as-if ) si l'objet modifié par cette fonction n'est plus accédé par la suite pendant sa durée de vie (par exemple, gcc bug 8537 ). Pour cette raison, cette fonction ne peut pas être utilisée pour effacer la mémoire (par exemple, pour remplir un tableau qui stockait un mot de passe avec des zéros).

Cette optimisation est interdite pour memset_explicit et memset_s : ils garantissent l'exécution de l'écriture en mémoire.

Les solutions tierces pour cela incluent FreeBSD explicit_bzero ou Microsoft SecureZeroMemory .

Exemple

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
    char str[] = "ghghghghghghghghghghgh";
    puts(str);
    memset(str,'a',5);
    puts(str);
#ifdef __STDC_LIB_EXT1__
    set_constraint_handler_s(ignore_handler_s);
    int r = memset_s(str, sizeof str, 'b', 5);
    printf("str = \"%s\", r = %d\n", str, r);
    r = memset_s(str, 5, 'c', 10);   // count is greater than destsz  
    printf("str = \"%s\", r = %d\n", str, r);
#endif
}

Sortie possible :

ghghghghghghghghghghgh
aaaaahghghghghghghghgh
str = "bbbbbhghghghghghghghgh", r = 0
str = "ccccchghghghghghghghgh", r = 22

Références

  • Norme C17 (ISO/CEI 9899:2018) :
  • 7.24.6.1 La fonction memset (p: 270)
  • K.3.7.4.1 La fonction memset_s (p: 451)
  • Norme C11 (ISO/CEI 9899:2011) :
  • 7.24.6.1 La fonction memset (p: 371)
  • K.3.7.4.1 La fonction memset_s (p: 621-622)
  • Norme C99 (ISO/CEI 9899:1999) :
  • 7.21.6.1 La fonction memset (p: 333)
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 4.11.6.1 La fonction memset

Voir aussi

copie un tampon vers un autre
(fonction)
(C95)
copie le caractère large donné à chaque position d'un tableau de caractères larges
(fonction)