Le manpage indique environ memset
:
#include <string.h> void *memset(void *s, int c, size_t n)
La fonction
memset()
remplit la premièren
octets de la zone mémoire désignée pars
avec l'octet constantc
.
Il est évident que memset
ne peut pas être utilisé pour initialiser le tableau int
comme indiqué ci-dessous:
int a[10];
memset(a, 1, sizeof(a));
c'est parce que int
est représenté par 4 octets (par exemple) et on ne peut pas obtenir la valeur souhaitée pour les entiers du tableau a
.
Mais je vois souvent que les programmeurs utilisent memset
pour définir les éléments du tableau int
sur 0
ou -1
.
int a[10];
int b[10];
memset(a, 0, sizeof(a));
memset(b, -1, sizeof(b));
Selon ma compréhension, l'initialisation avec l'entier 0
est correcte car 0
peut être représenté dans un octet (peut-être que je me trompe dans ce contexte). Mais comment est-il possible d’initialiser b
avec -1
(une valeur de 4 octets)?
Bizarrement, la raison pour laquelle cela fonctionne avec -1
est identique à la raison pour laquelle cela fonctionne avec des zéros: dans la représentation binaire du complément à deux , -1
a 1
s dans tous ses bits, quelle que soit la taille de l'entier, afin de remplir une région avec des octets remplis de tous les 1
s produit une région de -1
signé int
s, long
s et short
s sur du matériel à complément à deux.
Sur le matériel différent du complément à deux, le résultat sera différent. La constante entière -1
serait convertie en un unsigned char
de tous, car la norme spécifie la manière dont la conversion doit être effectuée. Cependant, une région d'octets dont tous les bits sont définis sur 1
serait interprétée comme une valeur intégrale conformément aux règles de la plate-forme. Par exemple, sur le matériel de signe et magnitude, tous les éléments de votre tableau contiendraient la plus petite valeur négative du type correspondant.
0
, sa valeur est également 0 . Cependant, si tous les bits sont1
la valeur est -1 .
Lorsque nous écrivons int a[2]
,4x2octets de mémoire sont alloués et contiennent des bits aléatoires/garbage-
00110000 00100101 11100011 11110010 11110101 10001001 00111000 00010001
Ensuite, nous écrivons memset(a, 0, sizeof(a))
. Maintenant, memset()
ne fait pas la distinction entre int
et char
. Cela fonctionne octet par octet. Et une représentation sur un octet de 0 est 00000000
. Donc, nous obtenons
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Par conséquent, a[0]
et a[1]
sont tous deux initialisés avec 0 .
Voyons maintenant memset(a, -1, sizeof(a))
: Un octet pour -1 est 11111111
. Et nous
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111
Ici, a[0]
et a[1]
auront la valeur -1 .
Cependant, pour memset(a, 1, sizeof(a))
: 1 dans un octet est 00000001
-
00000001 00000001 00000001 00000001 00000001 00000001 00000001 00000001
Ainsi, la valeur sera- 16843009 .