Question

Lorsque vous utilisez malloc et effectuez une manipulation de mémoire similaire, puis-je compter sur sizeof (char) toujours égal à 1?

Par exemple, je dois allouer de la mémoire pour N éléments de type char . Est-ce que multiplier par sizeof (char) est nécessaire:

char* buffer = malloc( N * sizeof( char ) );

ou puis-je compter sur sizeof (char) toujours 1 et ignorer la multiplication

char* buffer = malloc( N );

Je comprends tout à fait que sizeof soit évalué lors de la compilation et que le compilateur puisse même compiler la multiplication. La pénalité de performance sera donc minime et probablement nulle.

Je parle principalement de la clarté et de la portabilité du code. Cette multiplication est-elle toujours nécessaire pour le type char ?

Était-ce utile?

La solution

Bien que cela ne soit pas nécessaire, j’estime qu’une bonne pratique consiste à conserver le sizeof (caractère), car cela rend le code plus lisible et évite l’utilisation d’un nombre magique. En outre, si le code doit être modifié ultérieurement de sorte qu’au lieu d’un caractère, c’est la taille de quelque chose dans un pointeur pour cet objet, il est plus facile de modifier le code que si vous avez juste un "1".

Autres conseils

Par définition, sizeof (char) est toujours égal à 1. Un octet est la taille du caractère en C, quel que soit le nombre de bits dans un octet (8 sur le processeur de bureau commun).

L'exemple typique où un octet n'est pas 8 bits est le PDP-10 et autres anciennes architectures de type mini-ordinateur avec octets 9/36 bits. Mais les octets qui ne sont pas 2 ^ N deviennent extrêmement rares, je crois

De plus, je pense que c'est un meilleur style:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);

car cela fonctionne quel que soit le type de pointeur.

sizeof (char) est toujours égal à 1, quel que soit le type de manipulation de la mémoire que vous effectuez.

Cependant, sizeof (TCHAR) peut varier en fonction des options de votre compilateur.

Je considère cela comme un anti-pattern . Cela indique que le programmeur ne savait pas très bien ce qu'il faisait, ce qui jette immédiatement une lumière douteuse sur le reste du code.

Certes, ce n'est pas (cite Wikipedia) "inefficace", mais je le trouve "loin d'être optimal". Cela ne coûte rien à l'exécution, mais il encombre le code d'inutiles déchets inutiles, tout en signalant que quelqu'un le jugeait nécessaire.

Notez également que l'expression ne s'analyse pas en tant qu'appel de fonction: sizeof n'est pas une fonction. Vous n'appelez pas une fonction en lui passant le symbole magique char . Vous appliquez l'opérateur de préfixe unaire intégré sizeof à une expression. Dans ce cas, votre expression est convertie dans le type char , qui est écrit en C (caractère) .

Il est parfaitement possible, et vivement recommandé, d'utiliser sizeof sur d'autres expressions, cela donnera alors la taille de la valeur de l'expression:

char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);

Ceci imprimera 1 , toujours, sur toutes les implémentations C conformes.

Je suis également tout à fait d'accord avec David Cournapeau et envisage de répéter le type nom dans un malloc () -appeler à aussi une sorte de anti-motif.

Au lieu de

char *str;

str = malloc(N * sizeof (char));

que beaucoup écriraient pour allouer un tampon de chaîne d'une capacité de N caractères, j'irais avec

char *str;

str = malloc(N * sizeof *str);

Ou (pour les chaînes uniquement) omettez le sizeof comme indiqué ci-dessus, mais ceci est bien sûr plus général et fonctionne aussi bien pour tout type de pointeur.

Ce n'est pas nécessaire. Voir ici (par exemple).

sizeof (char) est défini par le standard C pour toujours être 1 (octet). Notez que, comme sizeof renvoie un nombre octets , le nombre de bits par octet n’a aucune importance (et dans la pratique, il est égal à 8 de toute façon).

Il est également important de noter que le compilateur sait statiquement que la valeur de sizeof (char) est égal à 1 et qu'il sait également que multiplier un nombre par un 1 statique implique que la multiplication n'a pas besoin d'être effectuée. le compilateur va l'optimiser. Les préoccupations de performance ne devraient pas entrer en ligne de compte pour ces motifs.

De "New C standard". Un commentaire économique et culturel ".

  1. Statistiques: 2,0% de la taille sont tirés de char et 1,5% - de caractères non signés . Page 1033 en version 1.2 du livre.
  2. page 1037.
  

Le nombre de bits dans la représentation d'un type de caractère est   sans importance. Par définition le nombre   d'octets en octets un type de caractère est   un.

     

Directives de codage Développeurs parfois   associer un octet contenant toujours   huit bits. Sur les hôtes où le   le type de caractère est 16 bits, cela peut   conduire à l'hypothèse incorrecte que   appliquer sizeof à un type de caractère   retournera la valeur 2.   Ces questions sont discutées ailleurs.

L'utilisation de sizeof (char) rend votre code plus lisible et portable.

Sur x86, nous savons tous qu’un caractère a 1 octet. Mais l'écrire explicitement contribue à clarifier vos intentions, ce qui est toujours une bonne chose.

En outre, que se passe-t-il si votre code est placé sur une autre plate-forme où un caractère ne représente pas un octet? Que se passe-t-il si un caractère ne contient que 4 bits?

D'accord, ce n'est pas nécessaire, mais cela ne ralentira pas votre temps d'exécution et cela vous rapportera dans les rares cas où vous aurez besoin de transférer votre code vers une architecture différente.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top