arriver C erreur: la conversion de non-scalaire du type requis
Hey, j'obtiens cette erreur:
error: conversion to non-scalar type requested
Voici mon structs:
typedef struct value_t value;
struct value{
void* x;
int y;
value* next;
value* prev;
};
typedef struct key_t key;
struct key{
int x;
value * values;
key* next;
key* prev;
};
Voici le code qui me donne des problèmes:
struct key new_node = (struct key) calloc(1, sizeof(struct key));
struct key* curr_node = head;
new_node.key = new_key;
struct value head_value = (struct value) calloc(1, sizeof(struct value))
Suis-je pas penser à utiliser calloc sur les structures? Aussi, j'ai une structure que j'ai créée et puis je veux mettre qui à un pointeur du même type struct mais d'avoir une erreur. Ceci est un exemple de ce que je fais:
struct value x;
struct value* y = *x;
cela me donne cette erreur
error: invalid type argument of ‘unary *’
Quand je le fais, y = x, j'obtiens cet avertissement:
warning: assignment from incompatible pointer type
Vous apprendre le C en posant des questions et en essayant différentes choses.. ainsi que de la lecture et de l'. Les gens comme vous sont si décourageant. Sérieusement? Vous ne pouviez pas écrire quelque chose de constructif?
OriginalL'auteur user972276 | 2012-01-26
Vous devez vous connecter pour publier un commentaire.
Vous essayez d'affecter un pointeur expression (le type de retour de malloc() et ses amis est void*) vers une struct type (struct new_node). C'est un non-sens. Aussi: le casting n'est pas nécessaire (et peut-être dangereux, car il peut cacher les erreurs)
le même problème avec les autres malloc() en ligne:
Plus d'erreurs: Vous êtes en omettant le 'struct' mot-clé (ce qui est permis en C++, mais le non-sens en C):
Mise à JOUR: utilisation des structures et des pointeurs vers des struct.
Oups. Mon mauvais. Que devrais-je l'appeler que? l'objet? trop de confusion, à mon humble avis. Pointeur par rapport aux non-pointeur semble plus adéquate.
Si je voulais juste un struct, pourrais-je faire "struct clé new_node;" et ne pas avoir à allouer la mémoire? ou dois-je allouer de la mémoire?
clé new_node; alloue de la mémoire sur la pile de sorte que vous n'avez pas à gérer à la main.
struct key new_node;
est Ok, mais: il alloue une variable automatique ("sur la pile") qui permettra de sortir de la portée ("devient invalide") une fois que la fonction retourne. (donc: vous ne pouvez pas retourner un pointeur vers elle, parce que l'objet cesse d'exister une fois que la fonction retourne)OriginalL'auteur wildplasser
Je ne pense pas que vous avez correctement compris
typedef
s.La commune idiome avec l'aide de typedefs pour la commodité de nommage est-ce:
Puis vous utilisez le type
foo_t
au lieu de la moins pratiquestruct foo
.Pour plus de commodité, vous pouvez combiner la structure de la déclaration et du
typedef
dans un seul bloc:Ceci définit une
foo_t
comme ci-dessus.La dernier un jeton sur le
typedef
ligne est le nom que vous attribuez. Je n'ai aucune idée de ce que le code que vous avez écrit est en train de faire de votre espace de noms, mais je doute que c'est ce que vous voulez.Maintenant, comme pour le code lui-même:
calloc
retourne un pointeur, ce qui signifie les deux votre plâtre et votre type de stockage doit êtrestruct key*
(ou, si vous corrigez votre dénomination,key_t
). La ligne correcte eststruct key* new_node = (struct key*)calloc(1, sizeof(struct key));
Pour votre deuxième, indépendant, à la question, la dernière ligne devrait être
struct value* y = &x;
. Vous souhaitezy
pour stocker les adresse dex
, pas la chose à l'adresse x. Le message d'erreur indique ce - que vous êtes une utilisation abusive de l'unaire star opérateur pour tenter de déréférencer un non-pointeur de variable.+1, sauf que vous ne devriez pas les types de nom se terminant par
_t
parce que POSIX ces réserves. Il en va de votre propre code et pour les petites applications, mais le code destiné à des fins de distribution ou de portabilité doit l'éviter.OriginalL'auteur Borealid
calloc
renvoie une valeur de type pointeur (void *
), que vous tentez de convertir et de les assigner à un agrégat (OIE, non scalaire) type (struct key
). Pour résoudre ce problème, modifiez le type denew_node
àstruct key *
et de réécrire votre affectation comme suit:Deux choses sont à noter. Tout d'abord, le fossé de la fonte d'expression.
malloc
,calloc
, etrealloc
tous de retourvoid *
, qui peuvent être assignées à n'importe quel objet de type pointeur sans avoir besoin d'un cast1. En effet, la présence d'un casting peut potentiellement masquer une erreur si vous oubliez d'inclurestdlib.h
ou autrement n'avez pas de déclaration pourmalloc
portée2.Deuxièmement, notez que j'utilise l'expression
*new_node
comme argument desizeof
, plutôt que de(struct key)
.sizeof
n'est pas de l'évaluer, de l'opérateur (sauf si c'est une variable de type tableau, ce qui n'est pas); il calcule le type de l'expression. Puisque le type de l'expression*new_node
eststruct key
,sizeof
va retourner le nombre d'octets pour stocker un objet. Il peut économiser de l'entretien des maux de tête si votre code est structuré commeet que vous changez le type de
foo
dans la déclaration, mais oublie de mettre à jour lemalloc
appel.Aussi, il n'est pas clair ce que vous voulez accomplir avec votre typedefs et struct définitions. Le code
n'est pas faire ce que vous pensez qu'il est. Vous êtes en train de créer un typedef nom
value
qui est un synonyme pour un non encore défini le type destruct value_t
. Cettevalue
type est différent de lastruct value
type vous créez plus tard (typedef noms et la structure des balises de vivre dans des espaces de noms différents). Réécrire vos structures de suivre ce modèle:Aussi, la vie sera plus facile si vous écrivez vos déclarations, de sorte que le
*
est associée à la déclaration, pas le spécificateur de type3. Une déclaration commeT* p
est analysé comme s'il avait été écritT (*p)
. Cela va vous sauver de l'embarras de l'écritureint* a, b;
et attend les deuxa
etb
être des pointeurs (b
est juste unint
).1 - C'est un domaine où le C et le C++ diffèrent; C++ ne pas permettre les conversions implicites entre
void *
et d'autres objets de type pointeur, donc si vous le compiler comme code C++, vous recevrez un message d'erreur au moment de la compilation. Aussi, avant 1989, la norme a été adoptée, le*alloc
fonctions retournéchar *
, donc dans ces jours, un casting était nécessaire si vous étiez de l'affectation à un autre type de pointeur. Cela ne devrait être un problème si vous travaillez sur un très vieux système.2 jusqu'à ce que la 1999 la norme, si le compilateur a vu un appel de fonction sans une précédente déclaration, il a assumé la fonction a retourné une
int
(qui est pourquoi vous avez encore de temps en temps voir des exemples commedans certains tutoriels;
main
est implicitement tapé pour revenirint
. Comme de C99, ce n'est plus autorisée). Donc, si vous oubliez d'inclurestdlib.h
et appelcalloc
(et vous n'êtes pas compiler comme C99), le compilateur suppose que la fonction retourne unint
et de générer le code machine en conséquence. Si vous laissez la fonte, le compilateur émet un diagnostic à l'effet que vous essayez d'affecter unint
de la valeur à un pointeur, ce qui n'est pas autorisé. Si vous laissez le plâtre, le code compile mais la valeur du pointeur peut être munged au moment de l'exécution (conversions de pointeurs versint
et à l'arrière pour encore les pointeurs ne sont pas garantis pour être significatif).3 - Il y a quelques rares cas, limitée à C++, où le
T* p
style peut rendre le code un peu plus clair, mais en général, vous êtes mieux à la suite de laT *p
style. Oui, c'est un avis personnel, mais qui est soutenu par un montant non négligeable de l'expérience.OriginalL'auteur John Bode
calloc
(3) renvoie une pointeur à la mémoire, qu'il alloue.devrait être
OriginalL'auteur Bertrand Marron
Vous ne devez pas affecter un pointeur vers un non-pointeur de variable. Changement new_node être un pointeur.
Aussi, utiliser l'adresse de la variable, vous devez
&
, pas*
, afin de le modifier pourstruct value* y = &x;
Edit: votre typedefs sont mauvais aussi. pour renverser la vapeur.
OriginalL'auteur asaelr
Pour le deuxième problème, vous souhaitez utiliser une esperluette "&" au lieu d'un astrisk "*". Un astrisk déréférence un pointeur, une esperluette vous donne le pointeur de la valeur.
c'est l'article dont je parlais: structure de la valeur* y = *x; doit être: structure de la valeur * y = &x;
OriginalL'auteur JKor