Est-ce que je lance le résultat de malloc?

Dans cette question , quelqu'un a suggéré dans un commentaire ce que je dois pas cast le résultat de malloc , c'est à dire

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

plutôt que:

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

pourquoi cela serait-il le cas?

2097
demandé sur Engineero 2009-03-03 13:13:02

26 réponses

Non ; vous ne pas cast le résultat, depuis:

  • il est inutile, car void * est promu automatiquement et en toute sécurité à tout autre type de pointeur dans ce cas.
  • il ajoute clutter au code, moulages ne sont pas très faciles à lire (surtout si le type de pointeur est long).
  • cela vous fait vous répéter, ce qui est généralement mauvais.
  • , Il peut cacher une erreur si vous avez oublié d'inclure <stdlib.h> . Cela peut causer des accidents (ou, pire, pas causer un accident jusqu'à bien plus tard dans une partie totalement différente du code). Considérez ce qui se passe si les pointeurs et les entiers sont de tailles différentes; alors vous cachez un avertissement en moulant et pourriez perdre des morceaux de votre adresse retournée. Note: à partir de C11 les fonctions implicites ont disparu de C, et ce point n'est plus pertinent puisqu'il n'y a pas de supposition automatique que les fonctions non déclarées retournent int .

Que d'une clarification, notez que j'ai dit "vous ne jette pas", pas "vous n'avez pas besoin jeter". À mon avis, c'est un échec d'inclure les acteurs, même si vous avez raison. Il n'y a tout simplement aucun avantage à le faire, mais un tas de risques potentiels, et y compris la distribution indique que vous ne savez pas au sujet des risques.

aussi noter, comme les commentateurs le font remarquer, que ce qui précède parle de C, Pas de c++. Je crois fermement que C et c++ sont des langues distinctes.

pour ajouter plus, votre code répète inutilement les informations de type ( int ) qui peuvent causer 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 également le length vers l'avant pour une visibilité accrue, et fait tomber les parenthèses redondantes 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! :)


en se déplaçant length vers l'avant mai augmenter la visibilité dans de rares cas, il faut également faire attention que dans le cas général, il devrait être préférable d'écrire l'expression as:

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

depuis le maintien du sizeof d'abord, dans ce cas, assure la multiplication est fait avec au moins size_t math.

Comparer: malloc(sizeof *sieve * length * width) vs malloc(length * width * sizeof *sieve) le deuxième peut déborder le length * width quand width et length sont de petits types de size_t .

1958
répondu unwind 2017-08-01 05:52:36

en C, vous n'avez pas besoin de lancer la valeur de retour de malloc . Le pointeur à vide retourné par malloc est automatiquement converti au type correct. Cependant, si vous voulez que votre code soit compilé avec un compilateur C++, Un cast est nécessaire. Une solution de rechange privilégiée dans la collectivité consiste à utiliser ce qui suit:

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

qui, de plus, vous évite d'avoir à vous soucier de changer le côté droit de l'expression si jamais vous changez le type de sieve .

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

332
répondu dirkgently 2015-12-11 15:15:48

vous do cast, parce que:

  • cela rend votre code plus portable entre C et c++, et comme le montre L'expérience, un grand nombre de programmeurs prétendent écrire en C alors qu'ils écrivent vraiment en C++ (ou en C plus extensions locales de compilateurs).
  • ne pas faire peut en cacher une erreur : remarque: toutes les exemples de la confusion quand à l'écriture de type * par rapport à type ** .
  • l'idée qu'il vous empêche de remarquer que vous avez échoué à #include un fichier d'en-tête approprié manque la forêt pour les arbres . C'est la même chose que de dire "ne vous inquiétez pas du fait que vous n'avez pas demandé au compilateur de se plaindre de ne pas voir de prototypes -- ce satané stdlib.h est la chose la plus importante à retenir!"
  • forces extra cognitive de la croix-cochez la case . Il met l' (présumé) type désiré juste à côté de l'arithmétique que vous faites pour la taille brute de cette variable. Je parie que vous pourriez faire une étude qui montre que les bogues malloc() sont attrapés beaucoup plus vite quand il y a un plâtre. Comme pour les assertions, les annotations qui révèlent l'intention réduisent les bogues.
  • se répéter d'une manière que la machine peut vérifier est souvent une grande idée. En fait, c'est ce que l'affirmation est, et cette utilisation de fonte est une affirmation. Les affirmations sont encore la technique la plus générale que nous ayons pour obtenir le code correct, puisque Turing a eu l'idée il y a tant d'années.
302
répondu Ron Burk 2016-11-02 14:54:07

comme d'autres l'ont dit, il n'est pas nécessaire pour C, mais pour C++. Si vous pensez que vous allez compiler votre code C avec un compilateur C++, Pour quelles raisons jamais, vous pouvez utiliser une macro à la place, 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 encore l'écrire d'une manière très compacte:

int *sieve = NEW(int, 1);

et il compilera pour C et C++.

153
répondu quinmars 2009-03-03 11:17:46

De la Wikipedia

avantages de la coulée

  • y compris la distribution peut permettre à un programme ou à une fonction C de se compiler en tant que C++.

  • la fonte permet des versions antérieures à 1989 de malloc qui ont à l'origine retourné un char *.

  • Coulée peut aider à la développeur identifier les incohérences dans le dimensionnement de type en cas de changement de type de l'aiguille de destination, en particulier si l'aiguille est déclarée loin de l'appel malloc () (bien que les compilateurs modernes et les analyseurs statiques peuvent avertir sur un tel comportement sans exiger la fonte).

inconvénients à la coulée

  • selon la norme ANSI C, la fonte est redondante.

  • ajouter la fonte peut masquer l'omission d'inclure l'en-tête stdlib.h , dans que le prototype de malloc a été trouvé. En l'absence d'un prototype pour malloc, la norme exige que le compilateur C supposons que malloc renvoie une int. S'il n'y a pas de coulée, un avertissement est émis lorsque cet entier est assigné au pointeur; cependant, avec la distribution, cet avertissement n'est pas produit, cachant un bug. Sur certains architectures et données modèles (tels que LP64 sur les systèmes 64 bits, où long et les pointeurs sont 64-bit et int est 32-bit), cette erreur peut il en résulte en fait un comportement indéfini, comme l'a implicitement déclaré malloc renvoie une valeur de 32 bits alors que la fonction définie par renvoie une valeur 64 bits. Selon les conventions d'appel et la mémoire mise en page, cela peut entraîner l'écrasement de la pile. Cette question est moins probable passer inaperçus dans les compilateurs modernes, car ils produisent uniformément Avertissements qu'une fonction non déclarée a été utilisé, donc un avertissement apparaissent toujours. Par exemple, le comportement par défaut de GCC est de montrer un avertissement qui se lit "déclaration implicite incompatible d'intégration fonction " que la distribution soit présente ou non.

  • si le type du pointeur est changé lors de sa déclaration, on peut aussi, besoin de changer toutes les lignes où malloc est appelé et moulé.

bien que malloc sans casting est la méthode préférée et la plupart des programmeurs expérimentés le choisissent , vous devriez utiliser celui que vous aimez avoir au courant des problèmes.

I. e: si vous devez compiler le programme C comme C++(Bien que ce soit un langage séparé), vous devez utiliser malloc avec casting.

105
répondu ashiquzzaman33 2017-12-26 12:04:52

en C vous pouvez convertir implicitement un pointeur de vide à n'importe quel autre type de pointeur, donc un plâtre n'est pas nécessaire. Le fait d'en utiliser une peut suggérer à l'observateur occasionnel qu'il y a une raison pour laquelle elle est nécessaire, ce qui peut être trompeur.

96
répondu PaulJWilliams 2012-05-13 00:35:43

vous ne lancez pas le résultat de malloc, parce que faire ainsi ajoute désordre inutile à votre code.

la raison la plus commune pour laquelle les gens jettent le résultat de malloc est parce qu'ils ne savent pas comment fonctionne le langage C. C'est un signe d'avertissement: si vous ne savez pas comment un mécanisme de langue particulier fonctionne, alors ne pas prendre une conjecture. Cherchez ou demandez sur le débordement de pile.

Quelques commentaires:

  • un pointeur de vide peut être converti en/à partir de n'importe quel autre type de pointeur sans moulage explicite (C11 6.3.2.3 et 6.5.16.1).

  • C++ ne permettra toutefois pas un moulage implicite entre void* et un autre type de pointeur. Donc en C++, la distribution aurait été correcte. Mais si vous programmez en C++, vous devez utiliser new et non malloc(). Et vous ne devriez jamais compiler du code C en utilisant un compilateur C++.

    si vous besoin de supporter à la fois C et c++ avec le même code source, utilisez des commutateurs de compilateur pour marquer les différences. Ne tentez pas d'établir les deux normes linguistiques avec le même code, car elles ne sont pas compatibles.

  • si un compilateur C ne trouve pas de fonction parce que vous avez oublié d'inclure l'en-tête, vous obtiendrez une erreur de compilateur/linker à ce sujet. Donc si vous avez oublié d'inclure <stdlib.h> ce n'est pas grand chose, vous ne serez pas en mesure de construire votre programme.

  • sur les compilateurs anciens qui suivent une version de la norme qui a plus de 25 ans, oublier d'inclure <stdlib.h> entraînerait un comportement dangereux. Parce que dans cet ancien standard, des fonctions sans prototype visible ont implicitement converti le type de retour en int . Le Casting du résultat de malloc explicitement serait alors cacher ce bug.

    , Mais c'est vraiment un non-problème. Vous n'êtes pas à l'aide d'un 25 ordinateur vieux de plusieurs années, alors pourquoi utiliser un compilateur vieux de 25 ans?

87
répondu Lundin 2018-04-12 08:53:05

en C vous obtenez une conversion implicite de void* vers n'importe quel autre pointeur (de données).

85
répondu EFraim 2012-05-13 00:35:15

Coulée la valeur retournée par malloc() n'est pas nécessaire maintenant, mais je voudrais ajouter un point qui semble que personne n'a relevé:

dans les temps anciens, c'est-à-dire avant ANSI C fournit le void * comme le type générique de pointeurs, char * est le type pour une telle utilisation. Dans ce cas, le plâtre peut arrêter les avertissements de compilateur.

référence: C FAQ

65
répondu Yu Hao 2014-02-14 02:28:44

il n'est pas obligatoire de lancer les résultats de malloc , car il renvoie void* , et un void* peut être pointé vers n'importe quel type de données.

48
répondu user968000 2015-06-03 06:10:35

juste en ajoutant mon expérience, en étudiant l'ingénierie informatique je vois que les deux ou trois professeurs que j'ai vu écrire en C ont toujours moulé malloc, cependant celui que j'ai demandé (avec un CV immense et la compréhension de C) m'a dit qu'il est absolument inutile, mais seulement utilisé pour être absolument spécifique, et pour amener les étudiants dans la mentalité d'être absolument spécifique. Essentiellement casting ne changera rien dans la façon dont il fonctionne, il fait exactement ce qu'il dit, attribue la mémoire, et le casting ne l'affecte pas, vous obtenez la même mémoire, et même si vous le moulez à quelque chose d'autre par erreur (et d'une manière ou d'une autre évitent les erreurs du compilateur) C Y accèdera de la même manière.

Edit: Coulée a un certain point. Quand vous utilisez la notation de tableau, le code généré doit savoir combien de places mémoire il doit avancer pour atteindre le début de l'élément suivant, ceci est réalisé par le casting. De cette façon vous savez que pour un double vous allez 8 bytes en avant alors que pour un int vous allez 4, et ainsi de suite. Ainsi il n'a pas d'effet si vous utilisez la notation pointeur, dans la notation de tableau il devient nécessaire.

47
répondu user3079666 2014-11-23 23:37:49

un pointeur de vide est un pointeur générique et c supporte la conversion implicite d'un type de pointeur de vide vers d'autres types, il n'y a donc pas besoin de le taper explicitement.

cependant, si vous voulez que le même code fonctionne parfaitement compatible sur une plate-forme C++, qui ne supporte pas la conversion implicite, vous devez faire la typographie, donc tout dépend de l'utilisabilité.

28
répondu Endeavour 2014-10-19 16:24:22

le type retourné est nul*, qui peut être moulé sur le type de pointeur de données désiré afin d'être déréférencable.

27
répondu swaps 2014-10-18 21:33:00

c'est ce que la référence de la bibliothèque GNU C manuel dit:

vous pouvez stocker le résultat de malloc dans n'importe quelle variable de pointeur sans cast, parce que ISO C convertit automatiquement le type void * en un autre type de pointeur si nécessaire. Mais la distribution est nécessaire dans les contextes autre que les opérateurs de tâche ou si vous voulez que votre code s'exécute dans la version traditionnelle C.

et en effet la norme ISO C11 (p347) dit:

le pointeur retourné si l'allocation réussit est convenablement aligné ainsi qu'il peut être affecté à un pointeur vers n'importe quel type d'objet avec un l'exigence fondamentale d'alignement et ensuite utilisé pour accéder à un tel objet ou un tableau de ces objets dans l'espace alloué (jusqu'à ce que le cents cinquante et une million neuf cent cinquante mille neuf cent vingt"

27
répondu Slothworks 2018-09-05 19:48:51

Cela dépend du langage de programmation et un compilateur. Si vous utilisez malloc en C, il n'est pas nécessaire de taper cast, car il Tapera automatiquement cast, mais si vous utilisez C++, vous devez taper cast parce que malloc retournera un type void* .

24
répondu Jeyamaran 2014-10-04 14:29:20

dans le langage C, Un pointeur de vide peut être assigné à n'importe quel pointeur, c'est pourquoi vous ne devriez pas utiliser un type de fonte. Si vous voulez une affectation "type safe", je peux vous recommander les fonctions macro suivantes, que j'utilise toujours dans mes projets C:

#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)

avec ceux-ci en place, vous pouvez simplement dire

NEW_ARRAY(sieve, length);

pour les matrices non dynamiques, la troisième macro de la fonction must-have est

#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

qui fait des boucles array plus sûr et plus pratique:

int i, a[100];

for (i = 0; i < LEN(a); i++) {
   ...
}
24
répondu August Karlstrom 2015-09-08 08:36:51

les gens utilisés pour GCC et Clang sont gâtés. Il n'est pas bon là-bas.

j'ai été assez horrifié au fil des ans par les compilateurs incroyablement âgés que j'ai dû utiliser. Souvent, les entreprises et les gestionnaires adoptent une approche ultra-conservatrice pour changer les compilateurs et ne vont même pas tester si un nouveau compilateur ( avec une meilleure conformité aux normes et l'optimisation du code ) fonctionnera dans leur système. La réalité pratique pour travailler développeurs est que lorsque vous codez, vous devez couvrir vos bases et, malheureusement, mallocs casting est une bonne habitude si vous ne pouvez pas contrôler quel compilateur peut être appliqué à votre code.

je suggérerais également que de nombreuses organisations appliquent leur propre norme de codage et que que devrait être la méthode que les gens devraient suivre si elle est définie. En l'absence de directives explicites, j'ai tendance à préférer compiler partout plutôt que un respect servile à une norme.

l'argument selon lequel ce n'est pas nécessaire selon les normes actuelles est tout à fait valable. Mais cet argument omet les aspects pratiques du monde réel. Nous ne codons pas dans un monde régi exclusivement par la norme du jour, mais par les aspects pratiques de ce que j'aime appeler "le domaine de la réalité de la gestion locale". Et c'est tordu et tordu plus que le temps spatial ne l'a jamais été. :- )

YMMV.

j'ai tendance à penser de lancer malloc comme une opération défensive. Pas jolie, pas parfaite, mais en général en sécurité. ( Honnêtement, si vous n'avez pas inclus stdlib.h puis vous avez chemin plus de problèmes que le casting malloc ! ).

14
répondu StephenG 2015-12-04 17:27:54

j'ai mis dans la fonte simplement pour montrer la désapprobation du trou laid dans le système de type, qui permet de code comme l'extrait suivant pour compiler sans diagnostics, même si aucun moulage sont utilisés pour provoquer la mauvaise conversion:

double d;
void *p = &d;
int *q = p;

j'aimerais que ça n'existe pas (et ça n'existe pas en C++) et donc j'ai lancé. Il représente mes goûts et ma Politique de programmation. Je ne suis pas seulement un pointeur, mais effectivement, un bulletin de vote, et casting les démons de la bêtise . Si je ne peux pas réellement chasser la stupidité , alors au moins laissez-moi exprimer le désir de le faire avec un geste de protestation.

en fait, une bonne pratique est d'envelopper malloc (et ses amis) avec des fonctions qui renvoient unsigned char * , et en gros de ne jamais utiliser void * dans votre code. Si vous avez besoin d'un pointeur Générique vers n'importe quel objet, utilisez un char * ou unsigned char * , et dans les deux directions. La seule détente qui peut être accordée, peut-être, est l'utilisation de fonctions comme memset et memcpy sans moulages.

sur le sujet de la compatibilité casting et C++, si vous écrivez votre code pour qu'il se compile en C et c++ (dans ce cas vous avez à cast la valeur de retour de malloc en l'assignant à quelque chose d'autre que void * ), vous pouvez faire une chose très utile pour vous-même: vous pouvez utiliser des macros pour casting qui traduit en C++ Style casts lors de la compilation en C++, mais réduire à un cast en C lors de la compilation en C:

/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif

si vous adhérez à ces macros, alors une simple recherche grep de votre base de code pour ces identificateurs vous montrera où sont tous vos casts, de sorte que vous pouvez vérifier si l'un d'eux est incorrect.

alors, à l'avenir, si vous compilez régulièrement le code avec C++, il imposera l'utilisation d'une distribution appropriée. Par exemple , si vous utilisez strip_qual juste pour supprimer un const ou volatile , mais le programme change de telle manière qu'une conversion de type est maintenant impliquée, vous obtiendrez un diagnostic, et vous devrez utiliser une combinaison de moulages pour obtenir la conversion désirée.

pour vous aider à adhérer à ces macros, le GNU C++ (pas C!) compilateur a une belle caractéristique: un diagnostic facultatif qui est produit pour toutes les occurrences de C style jette.

     -Wold-style-cast (C++ and Objective-C++ only)
         Warn if an old-style (C-style) cast to a non-void type is used
         within a C++ program.  The new-style casts (dynamic_cast,
         static_cast, reinterpret_cast, and const_cast) are less vulnerable
         to unintended effects and much easier to search for.

si votre code C se compile en C++, vous pouvez utiliser cette option -Wold-style-cast pour trouver toutes les occurrences de la syntaxe de casting (type) qui peuvent se glisser dans le code, et suivre ces diagnostics en le remplaçant par un choix approprié parmi les macros ci-dessus (ou une combinaison, si nécessaire).

ce traitement des conversions est la plus grande justification technique autonome pour travailler dans un "C propre": le C combiné et Le dialecte C++, qui à son tour justifie techniquement le casting de la valeur de retour de malloc .

12
répondu Kaz 2016-03-30 00:23:45

Coulée est seulement pour le C++ pas de C. Dans le cas où vous utilisez un compilateur C++ de mieux vous changer de compilateur C.

10
répondu 2015-09-10 15:58:49

La meilleure chose à faire lors de la programmation en C, lorsque cela est possible:

  1. faites compiler votre programme à l'aide d'un compilateur C avec tous les Avertissements activés -Wall et corrigez toutes les erreurs et tous les Avertissements
  2. s'assurer qu'il n'y a pas de variables déclarées comme auto
  3. puis compilez-le en utilisant un compilateur C++ avec -Wall et -std=c++11 . Corriger toutes les erreurs et les avertissements.
  4. maintenant compilez à nouveau en utilisant le compilateur C. Votre programme devrait maintenant compiler sans aucun avertissement et contenir moins de bogues.

cette procédure vous permet de profiter de la vérification de type stricte C++, réduisant ainsi le nombre de bogues. En particulier, cette procédure vous oblige à inclure stdlib.h ou vous aurez

malloc n'a pas été déclaré dans ce champ d'application

et vous oblige également à lancer le résultat de malloc ou vous obtiendrez

conversion invalide de void* en T*

ou quel que soit votre type de cible.

La seule les prestations de l'écriture en C au lieu de C++ je peux trouver sont

  1. C a une ABI bien spécifiée 1519140920"
  2. C++ peut générer plus de code [exceptions, RTTI, templates, runtime polymorphisme

notez que le second contre devrait dans le cas idéal disparaître lors de l'utilisation du sous-ensemble commun à C avec la caractéristique polymorphe statique .

pour ceux qui trouvent les règles strictes c++ incommodes, nous pouvons utiliser la fonctionnalité C++11 avec le type inféré

auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...
10
répondu user877329 2016-10-24 15:44:39

Non, vous ne jetez pas le résultat de malloc() .

en général, vous ne jetez pas à ou de void * .

une des raisons généralement invoquées pour ne pas le faire est que l'omission de #include <stdlib.h> pourrait passer inaperçue. Ce n'est plus un problème depuis longtemps maintenant que C99 a fait déclarations de fonction implicites illégal, donc si votre compilateur est conforme au moins C99, vous obtiendrez un diagnostic message.

mais il y a une raison beaucoup plus forte pour ne pas introduire de moulages de pointes inutiles:

dans C, un pointeur coulé est presque toujours une erreur . Cela est dû à la règle suivante ( §6.5 p7 dans N1570, le dernier projet pour C11):

un objet doit avoir sa valeur stockée accessible seulement par une expression de valeur qui a une de les types suivants:

- un type compatible avec le type effectif de l'objet,

- une version qualifiée d'un type compatible avec le type effectif de l'objet,

- un type qui est le type signé ou non signé correspondant au type en vigueur du objet,

- un type qui est le type signé ou non signé correspondant à une version efficace de l' objet,

- un agrégat ou un type d'union qui inclut l'un des types susmentionnés parmi ses membres (y compris, de façon récursive, un membre d'un sous-groupe ou d'un syndicat restreint), ou
1519320920" - un type de caractère.

c'est également connu sous le nom de règle d'alias stricte . Donc le code suivant est comportement non défini :

long x = 5;
double *p = (double *)&x;
double y = *p;

Et, parfois étonnamment, le suivant est aussi bien:

struct foo { int x; };
struct bar { int x; int y; };
struct bar b = { 1, 2};
struct foo *p = (struct foo *)&b;
int z = p->x;

parfois, vous do besoin de lancer des pointeurs, mais compte tenu de la stricte règle d'alias , vous devez être très prudent avec elle. Donc, toute occurrence d'un pointeur moulé dans votre code est un endroit où vous devez vérifier deux fois sa validité . Par conséquent,vous n'écrivez jamais un plâtre de pointeur inutile.

tl; dr

en un mot: parce que dans C, n'importe quel occurrence d'un pointeur moulé devrait lever un drapeau rouge pour le code nécessitant une attention particulière, vous ne devriez jamais écrire inutile pointeurs moulés.


notes:

  • Il ya des cas où vous réellement besoin un moulage à void * , p.ex. si vous voulez imprimer un pointeur:

    int x = 5;
    printf("%p\n", (void *)&x);
    

    la fonte est nécessaire ici, parce que printf() est une fonction variadique, donc les conversions implicites ne fonctionnent pas.

  • en C++, la situation est différente. Les types de pointeur Casting sont assez courants (et corrects) lorsqu'on traite des objets de classes dérivées. Par conséquent, il est logique que dans C++, la conversion en et de void * soit Non implicite. C++ a tout un ensemble de différentes saveurs de casting.

10
répondu 2017-11-08 08:54:22

je préfère faire le casting, mais pas manuellement. Mon préféré est d'utiliser g_new et g_new0 macros de glib. Si glib n'est pas utilisé, j'ajouterais des macros similaires. Ces macros réduisent la duplication de code sans compromettre la sécurité de type. Si vous vous trompez de type, vous obtiendrez un plâtre implicite entre des pointeurs non-void, ce qui provoquerait un avertissement (erreur en C++). Si vous oubliez d'inclure l'en-tête qui définit la g_new et g_new0 , vous obtiendrez une erreur. g_new et g_new0 tous les deux prennent les mêmes arguments, contrairement à malloc qui prend moins d'arguments que calloc . Il suffit d'ajouter 0 pour obtenir la mémoire initialisée zéro. Le code peut être compilé avec un compilateur C++ sans modifications.

10
répondu proski 2017-12-26 18:16:38

le concept derrière l'indicateur de vide est qu'il peut être moulé à n'importe quel type de données qui est pourquoi malloc retourne vide. Vous devez également être conscient de la typographie automatique. Il n'est donc pas obligatoire de lancer le pointeur, bien que vous devez le faire. Il aide à garder le code propre et aide à déboguer

9
répondu iec2011007 2015-07-29 05:53:42

un pointeur de vide est un pointeur générique et c supporte la conversion implicite d'un type de pointeur de vide vers d'autres types, il n'y a donc pas besoin de le taper explicitement.

cependant, si vous voulez que le même code fonctionne parfaitement compatible sur une plate-forme C++, qui ne supporte pas la conversion implicite, vous devez faire la typographie, donc tout dépend de l'utilisabilité.

5
répondu dhana govindarajan 2016-07-18 10:36:57
  1. comme d'autres l'ont dit, il n'est pas nécessaire pour C, mais pour C++.

  2. y compris la distribution peut permettre à un programme ou à une fonction C de se compiler sous la forme de C++.

  3. En C, il est inutile, comme void * est automatiquement et en toute sécurité promu à tout autre type de pointeur.

  4. Mais si vous lancez ensuite, il peut masquer une erreur si vous avez oublié d'inclure stdlib.h . Cela peut causer des accidents (ou, pire, ne pas causer un accident jusqu'à plus tard dans une partie totalement différente du code).

    parce que stdlib.h contient le prototype pour malloc est trouvé. Dans le en l'absence D'un prototype pour malloc, la norme exige que le C le compilateur suppose que malloc retourne un int. Si il n'y a pas de fonte, un avertissement est émis lorsque cet entier est affecté au pointeur; cependant, avec la fonte, ce avertissement n'est pas produit, cacher un bug.

5
répondu Mohit 2016-11-08 10:09:54

le moulage de malloc est inutile en C mais obligatoire en C++.

le moulage n'est pas nécessaire en C à cause de:

  • void * est promu automatiquement et en toute sécurité à tout autre type de pointeur dans le cas de C.
  • , Il peut cacher une erreur si vous avez oublié d'inclure <stdlib.h> . Cela peut causer des accidents.
  • si les pointeurs et les entiers sont de tailles différentes, alors vous cachez un avertissement en moulant et vous risquez de perdre des morceaux de votre adresse.
  • si le type du pointeur est modifié lors de sa déclaration, il peut également être nécessaire de changer toutes les lignes où malloc est appelé et moulé.

d'un autre côté, le moulage peut augmenter la portabilité de votre programme. I. e, il permet à un programme ou à une fonction C de se compiler en C++.

2
répondu Aashish 2018-09-09 14:00:42