IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Problème compilation dû à une structure


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2013
    Messages : 8
    Par défaut Problème compilation dû à une structure
    Bonjour à toutes et à tous, et au passage joyeuses fêtes.

    Je vous remercie tout d'abord de votre attention et du temps pris pour me répondre.
    Je m'excuse d'avance auprès des modérateurs si jamais mon topic est mal placé.

    Je suis actuellement étudiant en informatique, débutant en c, et j'ai un projet consistant à réaliser une bibliothèque de fonctions permettant d'utiliser des BigInteger (de grands entiers quoi).

    Je m'en sors plutôt bien pour le moment sauf que j'ai un problème lors de la compilation de mon programme.

    En effet j'ai une fonction newBigInteger qui me permet de transformer une chaîne de caractère en une liste doublement chainée qui regroupe par 4 les caractères et les inverse (apparemment c'est mieux ainsi d'après mon professeur). J'ai donc une structure BigInteger qui à comme éléments le signe (un entier) et une liste doublement chainée (ma chaine de caractère transformée).

    je vous joins le code et vous explique mon problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    typedef struct elem // Structure de la liste doublement chainée
    {
    	int valeur;
    	struct elem* precedent;
    	struct elem* suivant;
    
    } element;
    typedef element *DLlist;
    
    typedef struct // Structure BigInteger : un signe + une liste doublement chaînée
    {
        int sign;
        DLlist list;
    
    } dlstruct;
    
    typedef dlstruct *BigInteger;
    
    /* ***** FONCTIONS ***** */
    
    // newBigInteger
    
    BigInteger newBigInteger (char* chaine)
    {	
    	BigInteger b;
    	char* testchaine;
    
    	if (chaine==NULL)
    		exit(EXIT_FAILURE);
    	else
    	{
    		testchaine=strchr(chaine,'-');
    		if (testchaine==NULL)
    			b->sign=1;
    		else 
    		{		
    			b->sign=-1;
    			chaine++;
    		}
    		char *chaine2;
        		int longueur = strlen(chaine);  // Longueur est égale à la taille du nombre donné
        		DLlist l = creer(); // fonction qui permet de creer une liste vide
    		DLlist tmp;
    		int i = 4;
    		int a,b;
    
        		while(i<longueur)
    		{
            		chaine2= (&chaine[longueur-i]); 
    			a=atoi(chaine2);
    			ajouterq(l,a); /* fonction qui permet d'ajouter en queue de ma liste l'élément a */
    			chaine[longueur-i]='\0';
    			i=i+4;
    		}
    		b=atoi(chaine);
    		ajouterq(l,b);
    		tmp=supprimert(l); // fonction qui permet de supprimer la tête de ma liste
    		b->list=tmp; // ERROR : le problème est ici
    		
    	}
    	return b;
    }
    (ceci n'est qu'une partie de mon code car celui ci est très long....)

    Lorsque je compile mon programme, gcc me retourne:
    erreur: invalid type argument of ‘->’ (have ‘int’)
    b->list=tmp;
    ^

    J'ai eu beau chercher sur internet je n'arrive pas à trouver la solution... Puisque dans la suite, je réutilise "b->list" et il ne me considère plus celà comme une erreur...

    Je vous remercie encore du temps pris pour lire mon pavé juste immonde et pour le dérangement.
    Je m'excuse pour l'affichage désastreux de mon code.

    Merci.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Bonjour et bienvenue,

    Ton message est exactement à la bonne place (C→Débuter) et pour tout dire, cela fait plaisir de voir une demande rédigée comme la tienne, avec l'orthographe, les accents, la ponctuation, le code avec les bonnes balises et les formules de politesse ! Merci, donc, de nous aider à conserver un forum propre.

    Avant toute chose, sache que même si c'est une pratique très répandue dans les écoles, masquer un pointeur dans un typedef est une très mauvaise habitude, à ne jamais prendre en langage C.

    Ton problème vient du fait que tu as redéclaré « b ». Une fois en ligne 25 :
    … et une autre en ligne 45 :
    La variable la plus locale à un bloc masque les précédentes pendant la durée de son existence. J'ajoute également que le C original et C89 imposent que toutes les variables soient déclarées en début de bloc. C99 lève cette interdiction mais c'est toujours une bonne idée de conserver l'habitude de le faire quand même, car ces variables locales iront quand même dans la pile et, dans le cas contraire, quand un bloc commence à être long, il devient difficile de savoir si la variable référencée est celle locale au bloc ou la précédente ainsi que, le cas échéant, de retrouver la déclaration de la variable en question.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zthoustra Voir le message
    Citation Envoyé par Obsidian Voir le message
    Ton problème vient du fait que tu as redéclaré « b ». Une fois en ligne 25 :
    … et une autre en ligne 45 :
    ...mais c'est toujours une bonne idée de conserver l'habitude de le faire quand même, car ces variables locales iront quand même dans la pile et, dans le cas contraire, quand un bloc commence à être long, il devient difficile de savoir si la variable référencée est celle locale au bloc ou la précédente ainsi que, le cas échéant, de retrouver la déclaration de la variable en question.
    Bonjour
    Moi je rajouterais que si tu prends l'habitude de mettre des noms plus explicites que "a", "b" ou "c" tu risques moins de faire ce genre d'erreur...

    Citation Envoyé par Zthoustra Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int a,b;
     
    while(i<longueur)
    {
    	chaine2= (&chaine[longueur-i]); 
    	a=atoi(chaine2);
    	ajouterq(l,a); /* fonction qui permet d'ajouter en queue de ma liste l'élément a */
    	chaine[longueur-i]='\0';
    	i=i+4;
    }
    b=atoi(chaine);
    ajouterq(l,b);
    ...surtout que ici, la variable "b" est totalement inutile. Déjà tu peux réutiliser "a" qui ne sert plus après le while mais surtout tu peux utiliser directement atoi() => ajouterq(l, atoi(chaine)); (et pareil avec "a" qui n'est pas plus utile non plus)...

    PS: et peut-être aussi remplacer ce "4" par sizeof(int) pour être plus portable...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2013
    Messages : 8
    Par défaut
    Tout d'abord merci pour vos réponses claires précises. Effectivement, mon erreur était stupide et je m'excuse de vous avoir dérangé pour si peu...


    J'ai en revanche une nouvelle question. Maintenant je n'ai plus de problèmes au niveau de la compilation. Par contre, lorsque je lance mon programme il me dit qu'il y a une erreur de segmentation (core dumped)...Savez vous pourquoi? Sinon je peux rajouter la suite de mon code pour comprendre....

    Merci encore.

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Citation Envoyé par Zthoustra Voir le message
    J'ai en revanche une nouvelle question. Maintenant je n'ai plus de problèmes au niveau de la compilation. Par contre, lorsque je lance mon programme il me dit qu'il y a une erreur de segmentation (core dumped)...Savez vous pourquoi? Sinon je peux rajouter la suite de mon code pour comprendre....
    Une erreur de segmentation est une « segfault ». Ça veut dire que ton processus a tenté de lire ou d'écrire en mémoire mais en dehors du segment qui lui était alloué (et donc d'écraser ses petits copains voire même le système d'exploitation lui-même).

    C'est une erreur très fréquente en C et cela signifie que tu as soit un pointeur invalide quelque part (à 90 %), soit que tu dépasses la limite d'un tableau (si tu essais d'écrire dans le 11ème élément d'un tableau qui n'en compte que 10, le C ne t'empêchera pas de le faire), soit que tu fais un débordement de pile quelque part (spécialement vrai avec les fonctions récursives), soit que tu essaies d'accéder à de la mémoire que tu as déjà libéré au préalable, ou encore que tu essaies de la libérer une seconde fois.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zthoustra Voir le message
    Sinon je peux rajouter la suite de mon code pour comprendre....
    Je pense que là ce sera indispensable...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2013
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2013
    Messages : 8
    Par défaut
    Ok merci pour vos réponses toujours aussi rapides !

    Tout est lié à ma chaine de caractère du moins je le pense. Car j'ai fais différents test...

    Je vous explique ce que je pense être le problème. L'utilisateur du programme doit rentrer une chaine de caractère quelconque qui peut contenir 10000 caractères...Je pense donc que c'est possible mais c'est surement pour celà que mon programme plante (je dois faire péter la pile)...

    Le problème est qu'on ne peut pas prévoir la taille de cette chaine...

    Du coup je vous met la suite du code (mon main) pour plus de compréhension (car je n'ai pas l'impression d'être très clair)...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include "biginteger.h"
    #include "liste_doublmt_chainee.h"
     
    // Nécessaire pour le type boolean :
     
    #define TRUE 1
    #define FALSE 0
    typedef int boolean;
     
    /* ***** Fonction principale ***** */
     
    int main()
    {
        int choixMenu=0;
    	char *chaine;
     
        printf("\n~~~~ Menu ~~~~\n\n");
        printf("1:  newBigInteger\n");
        printf("2:  printBigInteger\n");
        printf("3:  isNull\n");
        printf("4:  signBigInt\n");
        printf("5:  equalsBigInt\n");
        printf("6:  compareBigInt\n");
        printf("7:  sumBigInt\n");
        printf("8:  diffBigInt\n");
        printf("9:  mulBigInt\n");
        printf("11: quotientBigInt\n");
        printf("12: restBigInt\n");
        printf("13: gcdBigInt\n");
        printf("14: lcmBigInt\n");
        printf("15: factorial\n");
        printf("16: cnp\n");
        printf("\n\nVeuillez choisir la fonction à utiliser en entrant le nombre correspondant :");
        scanf("%d", &choixMenu);
     
        switch (choixMenu)
        {
        case 1:
            printf("\n\nTapez le nombre :"); // il m'affiche bien ceci
            scanf(" %s", chaine);
    	printf("\n%s\n", chaine); // et également celà
            newBigInteger(chaine); .
            break;
    }

    Encore merci pour votre attention et votre temps pris pour répondre.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 477
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 477
    Par défaut
    Re-bonsoir,

    La fonction main() que tu nous présentes ici est incomplète. Cela dit, le problème vient de là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	char *chaine;
     
            scanf(" %s", chaine);
    	printf("\n%s\n", chaine); // et également celà
    Dans tous les cas, tu dois passer en argument un pointeur vers un endroit suffisamment grand et adapté pour recevoir la donnée qu'il va lire. Quand il s'agit d'un entier, ça ne pose pas de problème : tu passes directement l'adresse d'une variable de même type puisque la taille est fixe.

    Dans le cas d'une chaîne de caractères, en revanche, il faut que tu lui indiques un buffer, que tu auras donc dû allouer au préalable. Quand tu écris « char * chaine », tu déclares un pointeur sur un caractère et, par extension, sur ceux qui suivent, donc sur le début d'une chaîne. Mais ce pointeur ne pointe sur rien du tout a priori.

    Soit tu fais un malloc dont tu récupères le résultat dans ton pointeur « chaine » (sans oublier de le libérer en fin de programme), soit tu déclares directement un tableau à la place :
    Le fait d'invoquer le nom du tableau tout seul renvoie son adresse en mémoire, donc un pointeur de type char, et le reste de ton code demeure compatible.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur de compilation avec une structure
    Par existenz3 dans le forum Débuter
    Réponses: 3
    Dernier message: 10/12/2010, 09h07
  2. Problème d'accès à une structure.
    Par a_ferre dans le forum Débuter
    Réponses: 12
    Dernier message: 08/05/2008, 13h25
  3. Gtk: problème pour passer une structure en paramètres
    Par C_Chaou dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 19/04/2007, 19h29
  4. Réponses: 6
    Dernier message: 14/02/2006, 11h29
  5. Réponses: 7
    Dernier message: 21/12/2005, 16h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo