[C] Struct error

Résolu
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   -  
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,
J'ai un souci dans mon code et je m'arrache les cheveux avec ^^

typedef struct noeud{
	struct noeud* droit;
	struct noeud* gauche;
	int valeur;
}NOEUD;


typedef struct arbin{
	struct noeud* haut;
}ARBIN;


void new_noeud(arbin* a){                       //LIGNE 15 ICI
	noeud* n = (noeud*)malloc(sizeof(noeud));
	printf("Valeur ?");
	scanf("%d",(n->valeur));

    .....
}



Les erreurs sont :
ex1.c:15: erreur: expected ‘)’ before ‘*’ token
ex1.c: In function ‘main’:
ex1.c:64: attention : incompatible implicit declaration of built-in function ‘exit’

Voilou, HELP !! =)

17 réponses

fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
struct noeud* droit;
Il faut mettre struct Noeud. Même remarque pour gauche et haut.

exit(0);
Un simple return 0; fait l'affaire.

Sinon, ce qui explique le segmentation fault est une allocation oubliée.
arbin *arbre;
Il ne faut pas oublier de l'allouer non plus avec un joli malloc.

Cdlt,
1
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
printf("Ca a marche ? : %d \n",arbre->haut->gauche->valeur);
Si tu rentres 5 puis 4, ton arbre->haut->gauche vaudra NULL, seul arbre->haut->droit pointera sur une zone allouée avec la valeur 4. Ainsi en affichant arbre->haut->gauche->valeur, cela provoque un segfault assuré.
Pour afficher un arbre, il vaut mieux faire une fonction qui parcourt l'arbre en testant si gauche vaut NULL ou pas, pareil pour droit. S'ils ne sont pas NULL, alors on peut descendre d'un cran, ce qui facilite la récursivité.
De plus, n'oublie pas de mettre de bien initialiser les pointeurs à NULL lorsque tu alloues tes noeuds et même pour ton arbre. Sinon cela pourrait faire échouer tes conditions (qui portent sur des NULL).
Tu as laissé le exit(0) que je trouve vraiment très laid.
Et enfin, tu as oublié de libérer toutes les ressources allouées dans le programme. Il doit y avoir autant de free que de malloc. A toi donc de parcourir l'arbre pour faire tous les free nécessaires, sinon fuite de mémoire assurée.
1
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
il faut taper
void new_noeud(struct arbin* a){
ou
void new_noeud(ARBIN* a){
en C.
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Merci ^^
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
scanf("%d",&(n->valeur));

Cette ligne ne marche pas par contre... :/
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Ha ? pourquoi ?
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Erreur de segmentation
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Erreur de segmentation :/
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Bonjour,
Voici quelques corrections dans ton code. J'ai mis /*modif*/ lorsque ta ligne avait été modifiée.
De plus, j'ai enlevé le cast devant le malloc qui n'a plus lieu d'être à part alourdir le code.
void new_noeud(ARBIN* a){                       /*modif*/
	noeud* n = malloc(sizeof(NOEUD)); /*modif*/
	printf("Valeur ?");
	scanf("%d",&n->valeur); /*modif*/

Et enfin, n'oublie pas d'inclure stdlib.h pour inclure le prototype de la fonction exit(). C'est ce qui provoque ton warning.

Cdlt,
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Merci beaucoup Fiddy =)
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
J'ai testé ton code, et il doit y avoir une petite erreur encore :/
noeud* n = malloc(sizeof(NOEUD))


Cette ligne, je suis obligé d'écrire :

NOEUD n ...


Et il y a toujours mon erreur de segmentation dans ce qui suit, à la ligne indiquée.

#include <stdio.h>
#include <stdlib.h>

typedef struct noeud{
	struct noeud* droit;
	struct noeud* gauche;
	int valeur;
}NOEUD;


typedef struct arbin{
	struct noeud* haut;
}ARBIN;

void new_noeud(ARBIN* a){
	NOEUD* n = malloc(sizeof(NOEUD));                 
	printf("Valeur ?");
	scanf("%d",&n->valeur);       /*ICI, Erreur de segmentation (core dumped)*/

0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Cette ligne, je suis obligé d'écrire :
NOEUD n ...

Oui, tu as parfaitement raison, j'ai oublié de la signaler. Soit tu mets struct noeud, soit NOEUD. C'est d'ailleurs le but du typedef.

Ensuite pour l'erreur, elle n'a plus lieu d'être. Cela vient probablement d'un autre endroit de ton code.
Faudrait que tu postes davantage qu'on puisse avoir une meilleure visibilité.

Cdlt,
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
#include <stdio.h>
#include <stdlib.h>

typedef struct Noeud{
	struct noeud* droit;
	struct noeud* gauche;
	int valeur;
}noeud;

typedef struct Arbin{
	struct noeud* haut;
}arbin;

void new_noeud(arbin* a){
	noeud *n = malloc(sizeof(noeud));
	printf("Valeur ?");
	scanf("%d",&n->valeur);
	// printf("test : %d",n->valeur);

	int test = 1;
	
	if((*a).haut == NULL){
		(*a).haut = n;
	}/*
	else{	
		noeud* courant = a->haut;
	
		do{
			if((courant->valeur) <= (n->valeur)){
				if((courant->gauche) == NULL){
					courant->gauche = n;
					test = 0;
				}
				else
					courant = courant->gauche;
			}
			if((courant->valeur) > (n->valeur)){
				if((courant->droit) == NULL){
					courant->droit = n;
					test = 0;
				}
				else
					courant = courant->droit;
			}
		}while(test);
	}*/
}

int main(){
	arbin *arbre;
	if(arbre->haut == NULL)
		printf("OK");
	new_noeud(arbre);




	exit(0);
}
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Merci Fiddy pour tes explications, tout compile impeccable :)
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Je vais peut-être abuser dans mes questions, mais je ne comprend pas une dernière chose.

Lors de la saisie de nombre : 5, puis 6, tout marche bien.
Mais si je saisi 5 puis 4, ou 4 puis 3, ou 3 puis 2, ... etc, => Erreur de Segmentation
#include <stdio.h>
#include <stdlib.h>

typedef struct Noeud{
	struct Noeud* droit;
	struct Noeud* gauche;
	int valeur;
}noeud;

typedef struct Arbin{
	struct Noeud* haut;
}arbin;

void new_noeud(arbin* a){
	noeud *n = malloc(sizeof(noeud));
	printf("Valeur ?");
	scanf("%d",&n->valeur);
	printf("\n");
	// printf("Valeur %d rajoutee \n",n->valeur);

	int test = 1;
	printf("avant");
	if(a->haut == NULL){
		printf("1ere boucle");
		a->haut = n;
	}
	else{
		printf("2eboucle");
		// printf("boucle : %d",a->haut->valeur);
		noeud *courant = a->haut;
		// printf("boucle : %d \n",courant->valeur);
		do{
			printf("courant->valeur : %d ; valeur a placer : %d",courant->valeur,n->valeur);
			if((courant->valeur) <= (n->valeur)){
				if((courant->gauche) == NULL){
					courant->gauche = n;
					test = 0;
				}
				else
					courant = courant->gauche;
			}
			if((courant->valeur) > (n->valeur)){
				if((courant->droit) == NULL){
					courant->droit = n;
					test = 0;
				}
				else
					courant = courant->droit;
			}
		}while(test);
	}
}

int main(){
	arbin *arbre = malloc(sizeof(arbre));
	// if(arbre->haut == NULL)
		// printf("OK\n");
	new_noeud(arbre);
	printf("Ca a marche ? : %d \n",arbre->haut->valeur);
	new_noeud(arbre);
	printf("Ca a marche ? : %d \n",arbre->haut->gauche->valeur);
	new_noeud(arbre);
	new_noeud(arbre);
	
	free(arbre);
	exit(0);
}
0
Apaachee Messages postés 248 Date d'inscription   Statut Membre Dernière intervention   47
 
Tout est corrigé suivant tes conseils (très précieux), sauf pour les free ou je dois faire une fonction pour parcourir l'arbre pour "free" tous les noeuds.

Faire un free sur mon "arbre" du main ne cleanerait pas tout, je dois nécessairement les clean un par un ?
J'entend par la que si je free mon "arbre" du main, je n'ai plus de pointeur vers l'arbre mais l'espace reste alloué quand même ?

Comment faire un free de l'espace pointé par un pointeur, un free(arbre) suffit ? (arbre = pointeur)
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Faire un free sur mon "arbre" du main ne cleanerait pas tout, je dois nécessairement les clean un par un ?
Effectivement, tu dois nécessairement libérer les ressources une à une. le free(arbre) ne libère que la ressource occupée par l'arbre lui-même, mais pas par les feuilles. Il faut donc libérer les ressources allouées par les feuilles et remonter petit à petit jusqu'à la racine pour conclure par le free(arbre).

Cdlt,
0