HOWTO · Arduino
Fonction `memset()` sur Arduino
La fonction `memset()` remplit une plage d’octets avec une même valeur d’octet.
Sur cette page
memset() remplit un nombre donné d’octets à partir d’une adresse de destination en répétant la même valeur d’octet. Utilisez sizeof pour calculer le nombre d’octets d’un tableau et préférez une affectation typée si vous voulez donner une valeur numérique à chacun de ses éléments.
La fonction memset() dans Arduino
En C++ sur Arduino, memset() remplit une plage continue d’octets en répétant une valeur d’octet. Cette fonction convient aux tampons d’octets et aux tableaux de caractères ; elle ne copie pas une valeur de plusieurs octets dans chaque élément. Son troisième argument indique un nombre d’octets : calculez-le en fonction de la zone mémoire à remplir.
La fonction standard est déclarée dans <string.h> (également accessible avec l’en-tête C++ <cstring>). Sa forme est memset(destination, value, byte_count) : destination pointe vers le premier octet, value est converti en octet non signé et byte_count indique combien d’octets écrire. La fonction répète cet octet converti ; elle ne reprend pas les octets de la valeur d’origine.
Utiliser la fonction memset() dans Arduino
Cet exemple C++ complet remplit un tableau de caractères, puis en modifie une plage. Il utilise la sortie standard afin d’illustrer l’opération sans dépendre de la connexion série propre à une carte.
#include <cstring>
#include <iostream>
int main() {
char letters[] = "hello";
std::memset(letters, '.', sizeof(letters) - 1);
std::memset(letters + 1, 'a', 2);
std::cout << letters << '\n';
return 0;
}
.aa..
Le tableau dispose de l’espace nécessaire pour les cinq lettres et le caractère nul final. Le premier appel remplit uniquement les cinq octets des caractères visibles et laisse le caractère nul en place. Le second commence à l’indice 1 et écrit deux octets : il modifie donc les indices 1 et 2. Dans un programme Arduino, les mêmes opérations sur le tableau fonctionnent avec memset() ; utilisez Serial.print() pour afficher le tableau de caractères obtenu.
Pour un tableau d’un autre type, calculez le nombre d’octets à partir du tableau lui-même. Par exemple, memset(values, 0, sizeof(values)) remplit tous ses octets. Pour remplir une plage d’éléments entiers, avancez du nombre d’éléments voulu et multipliez ce nombre par la taille d’un élément : memset(values + start, byte_value, count * sizeof(values[0])). Les indices commencent à zéro et la plage choisie doit rester dans les limites du tableau.
Remplir un tableau d’entiers avec la valeur d’octet 2 n’affecte pas la valeur entière 2 à chaque élément. Sur une cible où int occupe 16 bits et où les octets sont ordonnés en petit-boutiste, chaque paire d’octets devient 0x0202, soit 514. Le résultat dépend de la largeur et de la représentation des entiers sur la cible. Pour affecter la valeur typée 2 à chaque élément, utilisez plutôt une boucle, par exemple for (int i = 0; i < count; ++i) values[i] = 2;.
Pour modifier des caractères dans un objet String Arduino, affectez directement ses caractères par indice, par exemple text[i] = '.';. Il s’agit d’une affectation directe de caractères, et non d’un usage de memset().
Points importants
Vérifiez toujours que la destination désigne une zone mémoire modifiable et que le nombre d’octets tient dans cette zone. Pour un tableau, sizeof(array) donne sa taille totale en octets uniquement tant que l’expression désigne encore le tableau lui-même ; un paramètre de fonction déclaré comme un tableau est un pointeur. Il faut donc transmettre ou calculer sa longueur séparément. Un nombre d’octets égal à zéro n’écrit rien, mais la destination doit tout de même être un pointeur valide au regard du contrat de la fonction.
La répétition d’un motif d’octets ne permet pas d’affecter des valeurs arbitraires à des objets. Elle convient lorsque la représentation au niveau des octets est voulue, par exemple pour remplir un tampon de caractères ou mettre des octets à zéro. Évitez de l’utiliser pour initialiser des objets C++ non triviaux, notamment ceux qui gèrent des ressources ou dépendent de constructeurs et d’invariants. Pour les valeurs et objets ordinaires, préférez une affectation typée, l’initialisation par valeur ou l’API propre à l’objet.
Conclusion
Utilisez memset() lorsque vous devez répéter un octet donné sur une plage d’octets dont la taille est connue. Calculez cette taille en octets, tenez compte de la largeur des éléments d’un tableau et veillez à ne jamais dépasser la zone mémoire de destination. Pour les entiers, les chaînes et les objets, privilégiez l’affectation typée ou la méthode d’initialisation adaptée, sauf si vous voulez précisément obtenir un motif d’octets répété.