Pourquoi “memset (arr, -1, sizeof (arr) / sizeof (int))” ne vide pas un tableau entier à -1?

N’est-il pas possible d’utiliser memset sur un tableau d’entiers? J’ai essayé l’appel memset suivant et je n’ai pas obtenu les valeurs entières correctes dans le tableau int.

int arr[5]; memset (arr, -1, sizeof(arr)/sizeof(int)); 

Vaules je suis sont:

 arr[0] = -1 arr[1] = 255 arr[2] = 0 arr[3] = 0 arr[4] = 0 

Changez simplement en memset (arr, -1, sizeof(arr));

Notez que pour d’autres valeurs que 0 et -1, cela ne fonctionnerait pas puisque memset définit les valeurs d’octet du bloc de mémoire qui commence à la variable indiquée par *ptr pour les octets suivants.

 void * memset ( void * ptr, int value, size_t num ); 

Et comme int est représenté sur plus d’un octet, vous n’obtiendrez pas la valeur souhaitée pour les entiers de votre tableau.

Des exceptions:

  • 0 est une exception puisque si vous définissez tous les octets sur 0, la valeur sera zéro
  • -1 est une autre exception puisque, puisque Pasortingck a mis en évidence -1 est 0xff (= 255) dans int8_t et 0xffffffff dans int32_t

La raison pour laquelle tu as:

 arr[0] = -1 arr[1] = 255 arr[2] = 0 arr[3] = 0 arr[4] = 0 

Est parce que, dans votre cas, la longueur d’un int est de 4 octets (représentation de 32 bits), la longueur de votre tableau en octets étant de 20 (= 5 * 4), et vous ne définissez que 5 octets sur -1 (= 255) au lieu de 20

N’utilisez pas memset pour initialiser autre chose que des types de données à un octet.

À première vue, il peut sembler que cela devrait fonctionner pour initialiser un int à 0 ou -1 (et sur de nombreux systèmes, il fonctionnera), mais vous ne tenez pas compte de la possibilité de générer une comportement indéfini, ou le fait que la représentation entière n’est pas nécessairement un complément à deux .

La manière correcte d’initialiser un tableau de type int sur -1 consiste à parcourir le tableau et à définir chaque valeur de manière explicite.

gcc fournit un bon raccourci d’initialisation de tableau

int arr[32] = {[0 ... 10] = 3, [11 ... 31] = 4}

attention à l’espace avant et après ...

Pourquoi la division?

 memset(arr, -1, sizeof(arr)); 

Votre version, sizeof(arr)/sizeof(int) , vous donne le nombre d’éléments dans le tableau.

Vous pouvez vous épargner de la saisie en initialisant directement le tableau:

 int arr[5] = {-1, -1, -1, -1, -1}; 

Cette ligne est plus courte que le memset et fonctionne également.

 void * memset ( void * ptr, int value, size_t num ); 

Cette fonction fonctionne bien sur la plupart des systèmes lorsqu’elle est appliquée à la définition d’un tableau de caractères. Il définit le premier num BYTES du bloc de mémoire pointé par ptr sur la valeur spécifiée (interprétée comme un caractère non signé). Référence memset-C ++ Il opère un octet à chaque fois. Cela fonctionne donc très bien si vous atsortingbuez les seconds arguments avec une valeur int ne dépassant pas 0xff.

En ce qui concerne votre version, le troisième argument est le nombre d’éléments du tableau, vous avez donc obtenu votre sortie. En fait, la vérité est que vous êtes censé atsortingbuer le troisième argument au nombre de octets que vous voulez. Donc, la version correcte devrait être comme ceci:

 memset (arr, -1, sizeof(arr));