L'utilisation de' sizeof(char) 'lors de L'allocation dynamique d'un' char ' est-elle redondante?
lors de la répartition dynamique char
s, 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)
?
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.
C99 projet de norme6.5.3.4
L'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.
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 malloc
est la même. malloc(120)
alloue de l'espace pour 120 char
.
char
doit être d'au moins 8 bits, mais peut-être plus.
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.
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.
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
.