L'utilisation de' sizeof(char) 'lors de L'allocation dynamique d'un' char ' est-elle redondante?

lors de la répartition dynamique chars, j'ai toujours fait comme ceci:

char *pCh = malloc(NUM_CHARS * sizeof(char));

on m'a dit récemment, cependant, qu'en utilisant sizeof(char) est redondant et inutile, car, "par définition, de la taille d'un char un octet," donc je devrait/pourrait écrire la ligne ci-dessus comme ceci:

char *pCh = malloc(NUM_CHARS);

Ma compréhension est la taille d'un char dépend du natif de jeu de caractères qui est utilisé sur l'ordinateur cible. Par exemple, si le jeu de caractères natif est ASCII, a char est un octet (8 bits), et si le natif jeu de caractères UNICODE char requerra nécessairement plus d'octets (> 8 bits).

Pour fournir un maximum de portabilité, ne serait-il pas nécessaire d'utiliser sizeof(char), comme malloc allocates simply 8-bit bytes? Suis-je malentendu malloc et sizeof(char)?

10
demandé sur Fiddling Bits 2013-12-19 18:19:24

6 réponses

Oui, c'est redondant, car la langue standard spécifie que sizeof (char) est 1. C'est parce que c'est l'unité dans laquelle les choses sont mesurés, alors, évidemment, la taille de l'unité elle-même doit être de 1.

la vie devient étrange avec des unités définies en termes d'elles-mêmes, cela n'a tout simplement aucun sens. Beaucoup de gens semblent "vouloir" supposer que "il y a des octets 8 bits, et sizeof me dit combien il y en a dans une valeur particulière". C'est mal, ce n'est tout simplement pas comme ça travail. C'est vrai qu'il peut y avoir des plates-formes avec des caractères plus grands que 8 bits, c'est pourquoi nous avons CHAR_BIT.

typiquement vous "savez" toujours quand vous attribuez des caractères de toute façon, mais si vous voulez vraiment inclure sizeof, vous devriez vraiment envisager de faire, utilisez le pointeur de la place:

char *pCh = malloc(NUM_CHARS * sizeof *pCh);

ceci "verrouille" la taille de l'Unité de la chose étant affectée le pointeur qui est utilisé pour stocker le résultat de l'allocation. Ces deux types devraient correspondre, si vous jamais voir le code comme ceci:

int *numbers = malloc(42 * sizeof (float));

c'est un énorme signal d'avertissement; en utilisant le pointeur de la gauche dans le sizeof vous faites ce type d'erreur impossible que je considère comme une grande victoire:

int *numbers = malloc(42 * sizeof *numbers);

aussi, il est probable que si vous changez le nom du pointeur, le malloc() ne compilera pas ce qu'il ferait si vous aviez le nom du type de base (erroné). Il existe un faible risque que si vous oubliez l'astérisque (et d'écrire sizeof numbers à la place sizeof *numbers) vous n'obtiendrez pas ce que vous voulez. En pratique (pour moi) cela ne semble jamais se produire, puisque l'astérisque est assez bien établi dans le cadre de ce modèle, pour moi.

en outre, cet usage repose sur (et souligne) le fait que sizeof n'est pas une fonction, car aucun ()s sont nécessaires autour de l'expression de-référencement du pointeur. C'est un joli bonus, car beaucoup de gens semblent vouloir le nier. :)

je trouve ce modèle très satisfaisant et le recommande pour tout le monde.

14
répondu unwind 2014-04-04 06:26:54

C99 projet de norme6.5.3.4L'opérateur sizeof paragraphe 3 états:

lorsqu'il s'applique à un opérande qui a le type char, non signé char, ou signé char, (ou une version qualifiée de celle-ci) le résultat est 1. [...]

dans le projet de norme C11, c'est le paragraphe 4 mais la formulation est la même. Donc NUM_CHARS * sizeof(char)devrait équivalent à NUM_CHARS.

nous pouvons voir de la définition de byte3.6 que c'est un:

unité adressable de stockage de données assez grande pour contenir n'importe quel membre du caractère de base ensemble de l'environnement d'exécution

et Note 2 dit:

Un octet est composé d'une séquence contiguë de bits, dont le nombre est définie par l'implémentation. Le morceau le moins significatif est appelé le bit de bas-ordre; le bit le plus significatif est appelé bit de haut-ordre.

5
répondu Shafik Yaghmour 2013-12-30 14:59:37

la spécification C indique que sizeof(char)1, aussi longtemps que vous avez affaire à des implémentations conformes de C c'est redondant.

l'Unité de taille utilisée par mallocest la même. malloc(120) alloue de l'espace pour 120 char.

char doit être d'au moins 8 bits, mais peut-être plus.

4
répondu Klas Lindbäck 2013-12-19 14:20:42

sizeof(char) retourne toujours 1 de sorte qu'il n'a pas d'importance si vous l'utilisez ou lente, il ne changera pas. Vous pouvez confondre cela avec des caractères UNICODE larges, qui ont deux octets, mais ils ont un type différent wchar_t vous devez donc utiliser sizeof dans ce cas.

Si vous travaillez sur un système où un octet est défini pour avoir 16 bits, puis sizeof(char) retournerait quand même 1 car c'est ce que l'architecture sous-jacente attribuerait. 1 octet avec 16 bits.

3
répondu Devolus 2013-12-19 14:21:55

la taille des allocations est toujours mesurée en unités de char, qui a la taille 1 par définition. Si vous êtes sur 9 bits de la machine, malloc comprend son argument comme un nombre d'octets de 9 bits.

3
répondu Matteo Italia 2013-12-19 14:24:56

sizeof(char) toujours 1, mais pas parce que char est toujours un octet (il ne doit pas l'être), mais plutôt parce que le sizeof l'opérateur renvoie la taille de l'objet/du type en unités de char.

2
répondu Simon Richter 2013-12-19 14:21:36