memset(3)

Fonction de la bibliothèque C

Remplit les n premiers octets d'une zone mémoire avec une valeur d'octet et renvoie l'adresse de la zone. Pratique pour mettre un tampon à zéro.

Synopsis
#include <string.h>
void *memset(void *s, int c, size_t n);

Description

memset écrit la même valeur dans les n premiers octets de la zone pointée par s. La norme C23 précise la conversion : la fonction « copies the value of c (converted to an unsigned char) into each of the first n characters ». Le c est un int, mais seuls ses 8 bits de poids faible comptent. C'est pour ça que memset(buf, 0, n) met tout à zéro, et memset(buf, '-', n) remplit de tirets.

L'emploi le plus courant est la remise à zéro d'un tampon ou d'une structure juste après l'allocation, quand calloc(3) ne convient pas (par exemple pour une variable de pile). Attention à une idée fausse fréquente : memset(tableau, 1, n) ne met pas chaque int à 1, il met chaque octet à 0x01, donc chaque int vaut 0x01010101. memset raisonne en octets, pas en éléments.

Valeur de retour

memset renvoie s, l'adresse qu'on lui a donnée. Comme pour memcpy et memmove, cette valeur permet surtout d'enchaîner.

Exemple

memset.c
#include <stdio.h>#include <string.h>
int main(void){    char ligne[6];
    memset(ligne, '-', 5);    ligne[5] = '\0';    printf("%s\n", ligne);    return 0;}
Terminal
$ gcc -Wall -Wextra -g memset.c -o memset$ ./memset-----

Pièges

  • Croire remplir des int avec une valeur : seul l'octet de poids faible de c est utilisé, répété sur chaque octet. Zéro est le seul cas qui donne la valeur attendue sur tous les types.

  • Confondre l'ordre des arguments : c'est memset(s, c, n), la valeur avant la taille. L'inverse de l'intuition pour beaucoup.

  • Compter sur memset(p, 0, n) pour effacer un secret qu'on va libérer : le compilateur peut supprimer l'appel s'il juge la zone inutilisée ensuite. C23 ajoute memset_explicit pour ce besoin précis.

  • Donner une taille en éléments et non en octets : pour un tableau d'int, c'est n * sizeof(int).

C

memset

Écris gm_memset, qui range l'octet de poids faible de c dans exactement n octets et renvoie le pointeur reçu, pas la fin de la zone.

Ouvrir l'exercice

À toi d'écrire le code.