2696 votes

Dois-je cast le résultat de la fonction malloc?

Dans cette question, quelqu'un a suggéré dans un commentaire que je ne devrais pas jeté les résultats de l' malloc, , je.e:

int *sieve = malloc(sizeof(int)*length);

plutôt que:

int *sieve = (int *)malloc(sizeof(int)*length);

Pourquoi serait-ce le cas?

2451voto

unwind Points 181987

Non; vous n'avez pas jeté le résultat, puisque:

  • Il est inutile, comme void * est automatiquement et en toute sécurité promu à tout autre type de pointeur dans ce cas.
  • Il peut se cacher une erreur, si vous avez oublié d'inclure <stdlib.h>. Cela peut provoquer des plantages, dans le pire des cas.
  • Il ajoute encombrer le code, les distributions ne sont pas très facile à lire (surtout si le pointeur est de type long).
  • Il fait de vous répéter vous-même, ce qui est généralement mauvais.

Une clarification, notez que j'ai dit "vous ne jette pas", pas "vous n'avez pas besoin de casting". À mon avis, c'est un échec pour inclure le casting, même si vous l'avez droit. Il y a tout simplement aucun avantage à le faire, mais un tas de risques potentiels, et notamment la distribution indique que vous ne savez pas sur les risques.

Notez également, que les commentateurs soulignent que les changements ci-dessus pour les droites C, pas du C++. Je crois fermement dans le C et le C++ comme des langues distinctes.

Pour ajouter d'autres, votre code inutilement répète les informations de type (int), ce qui peut provoquer des erreurs. Il est préférable de déréférencer le pointeur utilisé pour stocker la valeur de retour, pour "verrouiller" les deux ensemble:

int *sieve = malloc(length * sizeof *sieve);

Cela déplace aussi l' length à l'avant pour une meilleure visibilité, et les gouttes de la redondants entre parenthèses avec sizeof; ils ne sont nécessaires que lorsque l'argument est un nom de type. Beaucoup de gens semblent ne pas savoir (ou ignorer) ce qui rend leur code plus détaillé. Rappelez-vous: sizeof n'est pas une fonction! :)

453voto

dirkgently Points 56879

En C, vous n'avez pas besoin de jeter la valeur de retour de l' malloc. Le pointeur void retourné par malloc est automatiquement converties vers le bon type. Toutefois, si vous souhaitez que votre code à compiler avec un compilateur C++, un casting est nécessaire. Une alternative privilégiée au sein de la communauté est d'utiliser les éléments suivants:

int *sieve = malloc(sizeof *sieve * length);

ce qui vous évite de devoir vous soucier de changer le côté droit de l'expression si jamais vous changez le type d' sieve.

Les castes sont mauvais, comme les gens l'ont souligné. Spécialement pointeur de jette.

396voto

Ron Burk Points 1128

Vous n' en fonte, parce que:

  • Il rend votre code plus portable entre le C et le C++, et comme le montre l'expérience, un grand nombre de programmeurs affirment qu'ils sont écrit en C, quand ils sont vraiment écrit en C++ (ou C plus local compilateur extensions).
  • À défaut de le faire peut en cacher une erreur: remarque: toutes les exemples de la confusion quand à écrire * type de rapport type **.
  • L'idée que cela vous empêche de vous rendre compte de la échoué à #inclut le fichier d'en-tête est plutôt stupendously stupide. C'est la même chose que de dire "ne vous inquiétez pas sur le fait que vous avez omis de demander au compilateur de se plaindre de ne pas voir de prototypes -- ce fichus stdlib.h est la VRAIE chose importante à retenir!"
  • Il force un extra cognitive de la croix-case. Il met à la (prétendue) type désiré, juste à côté de l'arithmétique que vous faites pour le raw de la taille de la variable. Je parie que vous pourriez faire une SORTE d'étude qui montre que la fonction malloc (), des bugs sont pris beaucoup plus vite quand il y a un cast. Comme avec des affirmations, des annotations, qui révèlent l'intention de diminuer de bugs.
  • De vous répéter, de sorte que la machine peut vérifier est souvent une excellente idée. En fait, c'est ce que l'affirmation est, et cette utilisation de fonte est une affirmation. Les Assertions sont encore le plus général, technique que nous avons pour obtenir le code correct, depuis Turing est venu avec l'idée a tant d'années.

193voto

quinmars Points 4241

Comme d'autres l'avons mentionné, il n'est pas nécessaire pour le C, mais pour le C++. Si vous pensez que vous allez compiler votre code C avec un compilateur C++, pour les raisons qui font que jamais, vous pouvez utiliser une macro au lieu de cela, comme:

#ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif

De cette façon, vous pouvez toujours écrire de manière très compacte:

int *sieve = NEW(int, 1);

et compiler en C et C++.

116voto

PaulJWilliams Points 11641

En C, vous pouvez convertir implicitement un vide pointeur vers n'importe quel autre type de pointeur, donc un casting n'est pas nécessaire. À l'aide de on peut proposer pour l'observateur occasionnel qu'il y a une raison pour laquelle il est nécessaire, qui peut être trompeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X