Programme compile mais cesse de fonctionner dès le début
Répondre à la discussion
Affichage des résultats 1 à 14 sur 14

Programme compile mais cesse de fonctionner dès le début



  1. #1
    jameswell

    Programme compile mais cesse de fonctionner dès le début


    ------

    Bonjour,
    J'ai écrit un programme qui compile parfaitement mais qui plante dès le debut ( .exe a cessé de fonctionner ).
    La bibliothèque math.h n'a posé aucun problème pour toutes les compilations intermédiaires, donc je ne pense pas que le problème vienne de là.

    Voici mon programme : si quelqu'un pense avoir une idée... un grand merci d'avance

    Code:
    #include<stdio.h>
    #include<math.h>
    
    typedef struct square_matrix_s {
        int _size ;
        float values[100][100] ;
    } square_matrix ;
    
    typedef struct polynomial_s {
        int degree ;
        float coefficients[200] ;
    } polynomial ;
    
    typedef struct poly_square_matrix_s {
        int _size ;
        polynomial values[100][100] ;
    } poly_square_matrix ;
    
    int integermax(int a, int b){
        if (a>b) return a ;
        else return b ;
    }
    
    poly_square_matrix characteristic_matrix (square_matrix M) {
        poly_square_matrix N ;
        N._size = M._size ;
        int i,j ;
        for (i=0;i<M._size;i++) {
            for (j=0;j<M._size;j++) {
                polynomial P ;
                P.degree = 0 ;
                P.coefficients[0] = M.values[i][j] ;
                if (i==j) {
                    P.degree = 1 ;
                    P.coefficients[1] = -1 ;
                }
                N.values[i][j]=P ;
            }
        }
        return N ;
    }
    
    polynomial poly_add (polynomial a, polynomial b) {
        polynomial sum ;
        sum.degree = integermax(a.degree,b.degree) ;
        int i ;
        for (i=0;i<=sum.degree;i++) {
            sum.coefficients[i] = a.coefficients[i] + b.coefficients[i] ;
        }
        return sum;
    }
    
    polynomial poly_multiply (polynomial a, polynomial b) {
        int i,j ;
        polynomial product ;
        product.degree = a.degree+b.degree ;
        for (i=0;i<=product.degree;i++){
            product.coefficients[i]=0 ;
        }
        for (i=0;i<=a.degree;i++){
            for (j=0;j<=b.degree;j++){
                product.coefficients[i+j]=product.coefficients[i+j] + a.coefficients[i]*b.coefficients[j];
            }
        }
        return product ;
    }
    
    char sign(float a) {
        if (a>=0)
            return '+' ;
        return '-' ;
    }
    
    void check_polynomial_degree(polynomial *P) {
        int i=P->degree ;
        while (P->coefficients[i]==0&&i>0) {
            i=i-1 ;
        }
        P->degree = i ;
    
    }
    
    float absolute (float a) {
        if (a<0) return -a ;
        else return a ;
    }
    
    void display_monomial(float a, int k, int deg) {
        if(k!=0) {
            printf(" %c ",sign(a));
        }
        else {
            if (a<0) printf("-");
        }
        if (pow(a,2)!=1) printf("%f",absolute(a)) ;
        else {
                if (deg==0) printf("1") ;
        }
        if (deg==1) printf("X");
        else {
            if (deg>1) printf("X^%d",deg) ;
        }
    }
    
    void display_polynomial (polynomial P) {
        printf("\n");
        if (P.degree==0&&P.coefficients[0]==0)
            printf("0");
        else {
            int i,j=0 ;
            for (i=P.degree;i>=0;i=i-1) {
                if (P.coefficients[i]!=0) {
                    display_monomial(P.coefficients[i],j,i);
                    printf(" ");
                    j++;
                }
            }
        }
    }
    
    
    void enter_polynomial (polynomial *P) {
        printf("\n\nWhat degree is the polynomial ? ") ;
        scanf("%d",&(P->degree)) ;
        int i ;
        for (i=0;i<=P->degree;i++) {
            if(i==0) {
                printf("\nEnter constant coefficient : ") ;
            }
            else {
                if (i==1)
                    printf("\nX : ");
                else
                    printf("\nX^%d : ",i);
            }
            scanf("%f",&(P->coefficients[i])) ;
        }
        check_polynomial_degree(P);
        printf("\nThe polynomial you entered is of degree %d and is ",P->degree);
        display_polynomial(*P) ;
    }
    
    
    void display_menu (int *b) {
        printf("\n\nWhat do you want to do ?") ;
        printf("\n1. Calculate determinant") ;
        printf("\n2. Calculate characteristic polynomial") ;
        printf("\n");
        scanf("%d",b) ;
    }
    
    void display_matrix(square_matrix M) {
        int i,j ;
        printf("\n") ;
        for (i=0;i<M._size;i++) {
            for (j=0;j<M._size;j++) {
                printf("%f",M.values[i][j]) ;
                printf(" ") ;
            }
            printf("\n") ;
        }
        printf("\n") ;
    }
    
    void enter_matrix(square_matrix *M) {
        printf("\n\nWhat size is the matrix ? ");
        scanf("%i",&(M->_size)) ;
        int i,j ;
        printf("\nEnter the matrix¨s rows one after the other\nand press enter after each input: \n\n") ;
        for (i=0;i<M->_size;i++) {
            for (j=0;j<M->_size;j++) {
                scanf("%f",&(M->values[i][j])) ;
            }
        }
    }
    
    
    int placement(int offsquare, int newsquare) {
        if (offsquare<newsquare)
            return newsquare-1 ;
        else return newsquare ;
    }
    
    square_matrix reduce(square_matrix M, int a, int b) {
        square_matrix N ;
        N._size = M._size-1 ;
        int i,j ;
        for (i=0;i<M._size;i++) {
            for (j=0;j<M._size;j++) {
                    if(i!=a&&j!=b)
                        N.values[placement(a,i)][placement(b,j)]=M.values[i][j] ;
            }
        }
        return N ;
    }
    
    float determinant(square_matrix M) {
        float deter = 0 ;
        if (M._size != 1) {
            int i ;
            for (i=0;i<M._size;i++) {
                deter = deter + (pow((-1),i))*(M.values[i][0])*determinant(reduce(M,i,0)) ;
            }
            return deter ;
        }
        else
            return M.values[0][0] ;
    }
    
    polynomial poly_constant_multiply (int a, polynomial b) {
        polynomial P ;
        P.degree = 0 ;
        P.coefficients[0] = a ;
        return poly_multiply(P,b) ;
    }
    
    poly_square_matrix poly_reduce(poly_square_matrix M, int a, int b) {
        poly_square_matrix N ;
        N._size = M._size-1 ;
        int i,j ;
        for (i=0;i<M._size;i++) {
            for (j=0;j<M._size;j++) {
                    if(i!=a&&j!=b)
                        N.values[placement(a,i)][placement(b,j)]=M.values[i][j] ;
            }
        }
        return N ;
    }
    
    polynomial poly_determinant (poly_square_matrix M) {
        polynomial P ;
        P.degree = 0 ;
        P.coefficients[0]=0 ;
        if (M._size != 1) {
            int i ;
            for (i=0;i<M._size;i++) {
                P = poly_add(P,poly_constant_multiply((pow((-1),i)),poly_multiply(M.values[i][0],poly_determinant(poly_reduce(M,i,0))))) ;
            }
            return P ;
        }
        else
            return M.values[0][0] ;
    }
    
    int main (void) {
        int a = 1 ;
        int menu = 0 ;
        while(a>0) {
                display_menu(&menu) ;
                if (menu==1) {
                    square_matrix matrix ;
                    enter_matrix(&matrix);
                    display_matrix(matrix) ;
                    printf("\n\n%f",determinant(matrix)) ;
                }
                if (menu==2) {
                    square_matrix matrix ;
                    enter_matrix(&matrix);
                    printf("The characteristic polynomial is ");
                    display_polynomial(poly_determinant(characteristic_matrix(matrix))) ;
                }
        }
    return 0;
    }

    -----
    Dernière modification par JPL ; 30/12/2013 à 19h11. Motif: Ajout de la balise Code (#) pour garder l'indentation

  2. #2
    azad

    Re : Programme compile mais cesse de fonctionner dès le début

    Salut
    J'ai essayé de compiler ton programme en C avec le Xcode du Mac et j'obtiens, un BAD_ACCES à l'exécution (dans le main) de l'appel : display_menu(&menu) ; (thread error)
    En forçant menu à 1 ou à 2 et en n'appelant plus la fonction display_menu, j'obtiens la même erreur aux lignes
    enter_matrix(&matrix); (si menu =1)
    et
    enter_matrix(&matrix); (si menu =2)

    Par contre avec ObjectiveC et en remplaçant tous les Printf et surtout les Scanf ça tourne un peu mieux, et si ça fini par planter, c'est que je n'ai pas voulu ajouter des fenêtres à ton application (trop long en objectiveC)
    Je pense à des pointeur qui se baladent dans les scanf….

  3. #3
    Chanur

    Re : Programme compile mais cesse de fonctionner dès le début

    Tu déclares en automatique, tu passes par valeur à tes fonctions et tu retournes des variables de plus de 8 Mo !!!
    Je ne vois pas comment ça pourrait marcher ...
    Ou peut-être en forçant la stack a avoir une taille fantaisiste ?

    Mais pour moi, tu ferait mieux de déclarer tes variables static ou de les allouer dynamiquement et d'utiliser des pointeurs.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  4. #4
    bisou10

    Re : Programme compile mais cesse de fonctionner dès le début

    Autre chose. Quand l'éxécution d'un programme ne fonctionne pas, il est intéressant de le lancer dans l'IDE si possible, car souvent le debugguer te donne l'endroit de l'erreur (cas de Visual Studio par exemple).

  5. A voir en vidéo sur Futura
  6. #5
    azad

    Re : Programme compile mais cesse de fonctionner dès le début

    Tiens, j'ai trouvé un truc :
    Si tu met en commentaires

    /* polynomial poly_determinant (poly_square_matrix M) {
    polynomial P ;
    P.degree = 0 ;
    P.coefficients[0]=0 ;
    if (M._size != 1) {
    int i ;
    for (i=0;i<M._size;i++) {
    P = poly_add(P,poly_constant_multi ply((pow((-1),i)),poly_multiply(M.values[i][0],poly_determinant(poly_reduce( M,i,0))))) ;
    }
    return P ;
    }
    else
    return M.values[0][0] ;
    }
    */

    avec bien sûr dans le main

    // display_polynomial(poly_determ inant(characteristic_matrix(ma trix))) ;

    ton programme démarre normalement !

  7. #6
    jameswell

    Re : Programme compile mais cesse de fonctionner dès le début

    Merci à tous d'avoir tenté de m'éclaircir sur le sujet. Malheureusement je suis à la limite de mes connaissances sur le sujet et je ne sais pas ce que sont des "stack", ou des valeurs dynamiques. En fait je connais le langage mais pas grand chose sur l'environnement. Par contre j'ai réussi à trouver un extrait de mon programme beaucoup plus court (qui ne sert à rien en soi) qui agit de la même façon :

    Code:
    #include<stdio.h>
    
    typedef struct polynomial_s {
        int degree ;
        float coefficients[200] ;
    } polynomial ;
    
    typedef struct poly_square_matrix_s {
        int _size ;
        polynomial values[100][100] ;
    } poly_square_matrix ;
    
    int main (void) {
    poly_square_matrix N ;
    return 0;
    }
    Ces mêmes lignes de code se trouvent dans mon programme et compilent lorsqu'elles sont isolées comme ici mais elles renvoient la même erreur. Je suppose don que le problème vient de là. La seule hypothèse que je puisse émettre est que le deuxième
    Code:
    typedef
    definit un type structuré dont un des elements est de type
    Code:
    le premier type structuré
    et que cette imbrication de structures pose problème.
    De plus, dans le programme complet, il suffit d'enlever la ligne
    Code:
    display_polynomial(poly_determinant(characteristic_matrix(matrix))) ;
    qui se trouve dans le main pour que le programme fonctionne, ce qui revient à ne jamais utiliser ces structures imbriquées lors de l'exécution.

  8. #7
    azad

    Re : Programme compile mais cesse de fonctionner dès le début

    comme je te le disais plus haut

    avec bien sûr dans le main
    // on n'appelle plus la fonction
    // display_polynomial(poly_determ inant(characteristic_matrix(ma trix))) ;

    et ton programme démarre normalement !
    Mais ce qui est important c'est que l'erreur est dans le code objet quand on compile l'instruction en question, et non quand on l'exécute.

    On peut vérifier cela, en utilisant GDB.
    Il te faut donc voir si tous tes pointeurs sont correctement déclarés et initialisés.
    Dernière modification par azad ; 03/01/2014 à 00h44.

  9. #8
    Chanur

    Re : Programme compile mais cesse de fonctionner dès le début

    Citation Envoyé par jameswell Voir le message
    (...) Je suppose don que le problème vient de là. La seule hypothèse que je puisse émettre est que le deuxième
    Code:
    typedef
    definit un type structuré dont un des elements est de type
    Code:
    le premier type structuré
    et que cette imbrication de structures pose problème.
    Non, c'est parfaitement possible d'imbriquer les typedef.

    Ce qui ne l'est pas, par contre c'est de supposer que ta stack va faire plus de 8000000 octets !
    Je l'ai déjà dit, et tant que tu n'en tiendras pas compte et que tu garderas des variables automatiques de type poly_square_matrix, le problème restera ...
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  10. #9
    jameswell

    Re : Programme compile mais cesse de fonctionner dès le début

    Citation Envoyé par Chanur Voir le message
    Non, c'est parfaitement possible d'imbriquer les typedef.

    Ce qui ne l'est pas, par contre c'est de supposer que ta stack va faire plus de 8000000 octets !
    Je l'ai déjà dit, et tant que tu n'en tiendras pas compte et que tu garderas des variables automatiques de type poly_square_matrix, le problème restera ...
    D'accord, mais je ne sais pas ce qu'est un stack. Tu veux bien m'en dire plus ?
    Je suis prêt à tenir compte de tout, mais il faut que je comprenne.
    Merci d'avance

  11. #10
    Garlik

    Re : Programme compile mais cesse de fonctionner dès le début

    Ce que Chanur te dit, c'est que puisque ton type "poly_square_matrix" est un tableau de 100x100 "polynomial" et que chaque "polynomial" est composé d'un int et de 200 floats alors, si on suppose qu'un float et un int sont codés sur 4 octets, chaque variable de type "poly_square_matrix" va occuper 100x100xx201x4 = 8.040.0000 octets soit un bon 8 Mo.

    Ca va commencer à poser un problème si tu passes tes arguments par valeur et non par référence (ie par pointeur); dans ce cas au lieu de stocker un simple pointeur dans la pile, tu va copier l'intégralité de ta variable dans la pile, soit 8 Mo. C'est beaucoup. Très beaucoup. Trop en fait. Largement trop.

    Ce que tu observes, c'est donc un joli débordement de pile. Et ça continuera tant que tu persisteras à utiliser des objets aussi gros sans les référencer/manipuler par des pointeurs. Par ailleurs, quand il s'agit de créer une telle variable, on privilégie une allocation dynamique à une déclaration statique; ça évite de réserver de la mémoire pour toute la durée d'exécution du programme.

  12. #11
    galerien69

    Re : Programme compile mais cesse de fonctionner dès le début

    hello,
    Ca va commencer à poser un problème si tu passes tes arguments par valeur et non par référence (ie par pointeur);
    Le problème peut arriver bien avant. Des la création du tableau.

    Ce que tu observes, c'est donc un joli débordement de pile. Et ça continuera tant que tu persisteras à utiliser des objets aussi gros sans les référencer/manipuler par des pointeurs.
    On peut très bien manipuler un objet statique par un pointeur (ou une référence) ce qui ne résoud pas le problème. Il faut que le gros objet soit alloué dans la heap.
    Par ailleurs, quand il s'agit de créer une telle variable, on privilégie une allocation dynamique à une déclaration statique; ça évite de réserver de la mémoire pour toute la durée d'exécution du programme.
    cf dit au dessus, je suis juste revenu pour clarifier.
    la durée de vie d'une variable statique est définie par son scope.
    Code:
    void a(){
     BigTableau bigTableau;
    }
    int main(){
     a();
     //bigTableau n'existe plus
     //....des instructions ici...
    }
    le motif d'une allocation dynamique n'est pas de raccourcir la durée de vie d'une variable! c'est de l'augmenter.
    Mais dans ce cas c'est de permettre l'allocation de la variable car la taille de la heap (utilisée par une allocation dynamique) est plus grande que la taille de la stack (utilisée par une alloc statique comme fait jusqu'à présent).

  13. #12
    Chanur

    Re : Programme compile mais cesse de fonctionner dès le début

    Une variable peut être globale (déclarée en dehors de toute fonction) ou locale (déclarée dans une fonction)
    Une variable locale peut être statique (mot clef static) ou automatique (pas de mot clef (en fait on peut mettre "auto", mais c'est le cas par défaut et on ne le fait jamais))


    Il y a quatre zones de stockage des données en mémoire :
    - les registres
    - la stack (pile, en français)
    - le segment de données
    - la heap (tas)


    Les registres sont des zones internes au processeur. C'est ce qu'il y a de plus rapide mais c'est tout petit.
    Déclaration : register int toto;
    Inutile sauf si on est un forcené de l'optimisation et qu'on utilise un compilateur du siècle dernier, ou si on a une boucle qui s'exécute des milliards de fois. Le compilateur met lui-même en "register" les variables pour lesquelles ça a un intérêt (mais évidemment, un être humain peut faire preuve de plus de discernement dans le choix des variables).


    La stack est allouée au lancement du programme.
    Elle a une longueur fixe, pas énorme, a priori modifiable par les options de compilation, mais en principe la valeur par défaut suffit.
    Au lancement du programme, un pointeur vers la stack est initialisé.
    A chaque appel d'une fonction, le pointeur vers la stack est incrémenté de la taille correspondant à la somme de toutes les variables locales automatiques, y compris les arguments de la fonction.
    Au retour de la fonction, le pointeur de la stack est décrémenté pour reprendre sa valeur initiale.
    Celà permet à chaque appel de fonction d'allouer les variables locales automatiques, y compris dans le cas de fonction récursive : à chaque appel on prend une nouvelle tranche de la stack.
    A noter que ces variables ne sont jamais initialisées. A l'appel d'une fonction elle contiennent donc n'importe quoi, en fonction des appels précédents.


    Le segment de données est aussi alloué au lancement du programme.
    Je crois que sa longueur est définie par les variables qu'on y déclare : les variables globales et les variables locales statiques.
    Déclaration (dans une fonction) : static int toto;
    Le segment de données est entièrement rempli de 0 au lancement du programme.
    L'adresse des variables est défini une fois pour toutes, de sorte que si on appelle une deuxième fois une fonction les variables statiques gardent la valeur qu'elles avaient au retour du premier appel.
    Un exemple simple est de compter le nombre d'appel d'une fonction:
    Code:
    void fonction (void)
        {
        static int compteur;
        compteur++;
        [instructions de la fonction]
        }
    A chaque appel le compteur est incrémenté. Il garde sa valeur d'un appel à l'autre. Je ne l'ai pas initialisé puisqu'il est automatiquement mis à 0.
    (le mot clef static est aussi utilisé pour des variables globales, mais avec un sens complètement différent : il signifie alors qu'une variable n'existe que dans un seul fichier source. Si une variable du même nom existe dans un autre, c'est une variable différente.)


    La heap contient les variables allouées dynamiquement. Sa taille est indéfinie : elle varie dans le temps. A priori on dispose de toute la mémoire de l'ordinateur, voire plus s'il y a un mécanisme de mémoire virtuelle (utilisation du disque). Pour un système multi-utilisateur, il peut y avoir une limite par utilisateur ou peut-être aussi par programme.
    On alloue la mémoire en appelant une fonction (malloc, par exemple) qui retourne un pointeur vers la zone allouée.
    Exemple :
    Code:
    #include <stdlib.h>
    [les autres déclarations ...]
    typedef struct poly_square_matrix_s {
        int _size ;
        polynomial * values[100][100] ;
    } poly_square_matrix ;
    poly_square_matrix * characteristic_matrix (square_matrix * M) {
        poly_square_matrix * N ;
        N = malloc (sizeof (*N));
        N->_size = M->_size ;
        int i,j ;
        for (i=0;i<M->_size;i++) {
            for (j=0;j<M->_size;j++) {
                polynomial * P ;
                P = malloc (sizeof (*P));
                P->degree = 0 ;
                P->coefficients[0] = M->values[i][j] ;
                if (i==j) {
                    P->degree = 1 ;
                    P->coefficients[1] = -1 ;
                }
                N->values[i][j]=P ; // environ 10000 fois plus rapide que de recopier le polynomial
            }
        }
        return N ;
    }
    Tu noteras que j'ai modifié la déclaration de poly_square_matrix : values est maintenant un tableau de pointeurs vers des "polynomial" et non un tableau de "polynomial"
    J'ai aussi modifié le prototype de "characteristic_matrix" elle prend maintenant un pointeur en argument et retourne un pointeur : du coup je ne sature plus la stack.
    Attention une variable allouée dynamiquement doit être libérée (en utilisant la fonction "free"), sinon elle occupe la place jusqu'à l'arrêt du programme.
    La fonction malloc n'initialise pas la zone qu'elle alloue. Si on veut l'initialiser on peut utiliser calloc qui pave la mémoire de 0 ou écrire soi-même l'initialisation.


    Bon, tout ça fait un gros pavé, et je ne suis pas sûr d'avoir toujours été clair. N'hésite pas à demander plus d'explications, et bon courage ...
    Dernière modification par Chanur ; 19/01/2014 à 07h11.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  14. #13
    Jack
    Modérateur

    Re : Programme compile mais cesse de fonctionner dès le début

    je ne suis pas sûr d'avoir toujours été clair
    Au contraire, je trouve ton exposé clair et concis

  15. #14
    Chanur

    Re : Programme compile mais cesse de fonctionner dès le début

    Oups !
    J'ai oublié un point important : quand on fait une allocation dynamique, il faut TOUJOURS contrôler la valeur de retour (contrairement à l'exemple que j'ai donné).
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

Discussions similaires

  1. Internet explorer 10 a cessé de fonctionner
    Par RUBISS dans le forum Logiciel - Software - Open Source
    Réponses: 9
    Dernier message: 13/04/2013, 19h29
  2. [Thermique] radiateur ACOVA a cessé de fonctionner
    Par roghof dans le forum Dépannage
    Réponses: 4
    Dernier message: 29/12/2012, 09h12
  3. Réponses: 11
    Dernier message: 04/11/2012, 20h32
  4. .exe qui cesse de fonctionner...
    Par invite016c063e dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 21/10/2009, 23h16
  5. Internet à cessé de fonctionner ???
    Par invitef0b77be6 dans le forum Internet - Réseau - Sécurité générale
    Réponses: 4
    Dernier message: 06/01/2008, 19h27