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.
#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
#include <stdio.h>#include <string.h>
int main(void){ char ligne[6];
memset(ligne, '-', 5); ligne[5] = '\0'; printf("%s\n", ligne); return 0;}$ gcc -Wall -Wextra -g memset.c -o memset$ ./memset-----Pièges
Croire remplir des
intavec une valeur : seul l'octet de poids faible decest 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 ajoutememset_explicitpour ce besoin précis.Donner une taille en éléments et non en octets : pour un tableau d'
int, c'estn * sizeof(int).
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.