Langage c : erreur de segmention, tableaux 2D

Fermé
King - Modifié le 10 févr. 2022 à 16:02
mamiemando Messages postés 33458 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 8 janvier 2025 - 10 févr. 2022 à 15:46
Bonjour,

J’ai effectué un programme en langage c mais il m’affiche m. exe a cessé de fonctionner
Pourquoi ?
A voir également:

4 réponses

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
9 févr. 2022 à 23:04
Bonjour,

C'est écrit dans ton code ce qui le fait planter.
0
Non
0
Voici mon code source :

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

void equation(int a, int b, int c, int d);
int matricesomme(int M1[30][30], int M2[30][30], int S[30][30], int L1, int L2, int C1, int C2);
int nombrepaireetimpaire(int tab[30], int k, int nb);
int moyennemaxetmin(int tab[30], int k, int max, int moy, int min, int somme);

int menu(){
    int choix;
    printf("\n0.quitter\n");
    printf("1.equation de 2nd degre\n");
    printf("2.somme de deux matrice\n");
    printf("3.parite des nombre d'un tableau\n");
    printf("4.determiner la moyenne la note max et la note min des notes d'un tableau\n");
    printf("........................................................................................\n");
    printf("                                                            faites votre choix :");
    scanf("%d", &choix);
    return choix;
}

void equation(int a, int b, int c, int d)
{
    float x0, x1, x2;
    printf("entrer a :");
    scanf("%d", &a);
    printf("entrer b :");
    scanf("%d", &b);
    printf("entrer c :");
    scanf("%d", &c);
    d = (b * b) - (4 * a * c);
    if (d == 0) {
        x0 = (-b) / (2 * a);
        printf("l'equation admet une unique solution x0 = %f", x0);
    }
    else if (d > 0) {
        x1 = (-b - sqrt(d)) / (2 * a);
        x2 = (-b + sqrt(d)) / (2 * a);
        printf("equation admet deux solutions x1 = %f et x2 = %f", x1, x2);
    }
    else if (d < 0) {
        printf("equation admet aucune solution dans lR");
    }
    return 0;
}

int matricesomme(int M1[30][30], int M2[30][30], int S[30][30], int L1, int L2, int C1, int C2)
{
    int i, j;
    printf("somme de deux matrice");
    printf("\n");

    // matrice M1
    do {
        printf("entrer le nombre de ligne de la matrice M1 :");
        scanf("%d", &L1);
        printf("entrer le nombre de colonne de la matrice M1 :");
        scanf("%d", &C1);}
    while ((L1 < 0||L1 > 50) && (C1 < 0||C1 > 50));

    printf("remplisage de la matrice M1 :");
    printf("\n");
    for (i = 0; i < L1; i++) {
        for (j = 0;j < C1;j++) {
            printf("entrer les elements de la matrice M1[%d][%d] :", i, j);
            scanf("%d", &M1[i][j]);
        }
    }
    //affichage de la matrice M1
    printf(" la  matrice M1 est :");
    for (i = 0; i < L1; i++) {
        printf("\n");
        for (j = 0;j < C1;j++) {
            printf("%d\t", M1[i][j]);
        }
    }
    printf("\n");

    // matrice M2
    do{
        printf("entrer le nombre de ligne de la matrice M2 :");
        scanf("%d", &L2);
        printf("entrer le nombre de colonne de la matrice M2 :");
        scanf("%d", &C2);}
    while ((L2 < 0||L2 > 50) && (C2 < 0||C2 > 50));

    printf("remplissage de la matrice M2 :");
    printf("\n");
    for (i = 0; i < L2; i++) {
        for (j = 0;j < C2;j++) {
            printf("entrer les element de la matrice M2[%d][%d] :", i, j);
            scanf("%d", &M2[i][j]);
        }
    }
    printf("\n");
    //a&fficharge de la matrice M2
    printf(" la  matrice M2 est :");
    for (i = 0; i < L2; i++) {
        printf("\n");
        for (j = 0;j < C2;j++) {
            printf("%d\t", M2[i][j]);
        }
    }
    printf("\n");

    printf("la somme des deux matrice");
    printf("\n");
    if (L1 == L2 && C1 == C2) {
        for (i = 0;(i < L1 && i < L2); i++) {
            for (j = 0;(j < C1 && j < C2);j++) {

                S[i][j] = M1[i][j]+M2[i][j];
            }
        }
        //afficharge de la   somme
        printf(" la matrice S est :");
        for (i = 0;(i < L1 && i < L2); i++) {
            printf("\n");
            for (j = 0;(j < C1 && j < C2);j++) {
                printf("%d\t", S[i][j]);

            }
        }
        return 1;
    }
    else printf("erreur!les nombres de lignes et de colonnes de la matrice M1 doivent etre egale a celle de la matrice M2");

    return 0;
}
int nombrepaireetimpaire(int tab[30], int k, int nb)
{int i;
    printf(" entrer la dimention du tableau\n");
    scanf("%d", &k);
    if (k <= 50) {
        for (i = 0; i < k; i++) {
            printf("entrer les element du tableau tab[%d]\n", i);
            scanf("%d", &tab[i]);
        }
        //afficharge du tableau
        printf("le tableau est\n");
        for (i = 0; i < k; i++) {
            printf("%d", tab[i]);
            printf("\n");
        }

        for (i = 0; i < k; i++) {
            nb = tab[i] % 2;
            if (nb == 0) {
                printf("le nombre %d est paire\n", tab[i]);
            } else {
                printf("le nombre %d est impare\n", tab[i]);
            }
        }
        return 1;
    }else{
        printf("erreur!entrer une dimension plus petite que 30\n");
    }
    return 0;
}

int moyennemaxetmin(int tab[30], int k, int max, int moy, int min, int somme)
{
    int i;
    printf("entrer la dimensuion du tableau\n");
    scanf("%d", &k);
    if (k <= 50) {
        for (i = 0; i < k; i++) {
            printf("entrer les element du tableau %d\n", i);
            scanf("%d", &tab[i]);
        }
        //afficharge du tableau
        printf("le tableau est\n");
        for (i = 0; i < k; i++) {
            printf("%d", tab[i]);
            printf("\n");
        }

        max = tab[0];
        for (i = 0; i < k; i++) {
            if (max < tab[i]) {
                max = tab[i];
            }
        }
        min = tab[0];
        for (i = 0; i < k; i++) {
            if (min > tab[i]) {
                min = tab[i];
            }
        }

        printf("le maximun est %d\n", max);
        printf("le minimin est %d\n", min);
        somme = 0;
        for (i = 0; i < k; i++) {
            somme += tab[i];
        }
        moy = (somme) / k;
        printf("la moynenne est %f\n", moy);
        return 1;

    } else {
        printf("erreur!entrer une dimension plus petite ou egale a 50\n");
    }

    return 0;
}

int main(){
    int a, b, c, d;
    int M1[30][30], M2[30][30], S[30][30];
    int tab[30];
    int k, nb;
    int max, moy, min, somme;
    int i, j;
    int L1, L2, C1, C2;
    int choix;
    do {
        choix = menu();
        switch (choix) {
            case 0:
                break;
            case 1:
                equation(a, b, c, d);
                break;
            case 2:
                matricesomme(M1[30][30], M2[30][30], S[30][30], L1, L2, C1, C2);
                break;
            case 3:
                nombrepaireetimpaire(tab[30], k, nb);
                break;
            case 4:
                moyennemaxetmin(tab[30], k, max, moy, min, somme);
                break;
            default:
                printf("choix errone !!!\n\n");
        }
    } while (choix != 0);

    return 0;
}
0
mamiemando Messages postés 33458 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 8 janvier 2025 7 813
Modifié le 10 févr. 2022 à 16:05
Bonjour,

Merci de partager un code correctement indenté (voir message #3 une fois corrigé), si tu utilises un éditeur texte prévu pour faire du développement, il devrait t'aider à indenter le code.

Il y a de nombreuses erreurs, dont certaines que j'ai corrigées dans ton message #3
  • Il manquait le
    #include <math.h>
    (nécessaire pour utiliser
    sqrt
    )
  • À la compilation il faut veiller à linker avec la librarie maths (option
    -lm
    pour
    gcc
    ) e.g.
    gcc -W toto.c -lm -o toto.exe


Cela dit, il reste de nombreuses erreurs de compilation, et généralement un warning n'est jamais bon signe :

toto.c: In function ‘equation’:
toto.c:45:12: warning: ‘return’ with a value, in function returning void
45 | return 0;
| ^
toto.c:23:6: note: declared here
23 | void equation(int a, int b, int c, int d)
| ^~~~~~~~
toto.c: In function ‘main’:
toto.c:227:36: warning: passing argument 1 of ‘matricesomme’ makes pointer from integer without a cast [-Wint-conversion]
227 | matricesomme(M1[30][30], M2[30][30], S[30][30], L1, L2, C1, C2);
| ~~~~~~^~~~
| |
| int
toto.c:48:22: note: expected ‘int (*)[30]’ but argument is of type ‘int’
48 | int matricesomme(int M1[30][30], int M2[30][30], int S[30][30], int L1, int L2, int C1, int C2)
| ~~~~^~~~~~~~~~
toto.c:227:48: warning: passing argument 2 of ‘matricesomme’ makes pointer from integer without a cast [-Wint-conversion]
227 | matricesomme(M1[30][30], M2[30][30], S[30][30], L1, L2, C1, C2);
| ~~~~~~^~~~
| |
| int
toto.c:48:38: note: expected ‘int (*)[30]’ but argument is of type ‘int’
48 | int matricesomme(int M1[30][30], int M2[30][30], int S[30][30], int L1, int L2, int C1, int C2)
| ~~~~^~~~~~~~~~
toto.c:227:59: warning: passing argument 3 of ‘matricesomme’ makes pointer from integer without a cast [-Wint-conversion]
227 | matricesomme(M1[30][30], M2[30][30], S[30][30], L1, L2, C1, C2);
| ~~~~~^~~~
| |
| int
toto.c:48:54: note: expected ‘int (*)[30]’ but argument is of type ‘int’
48 | int matricesomme(int M1[30][30], int M2[30][30], int S[30][30], int L1, int L2, int C1, int C2)
| ~~~~^~~~~~~~~
toto.c:230:41: warning: passing argument 1 of ‘nombrepaireetimpaire’ makes pointer from integer without a cast [-Wint-conversion]
230 | nombrepaireetimpaire(tab[30], k, nb);
| ~~~^~~~
| |
| int
toto.c:131:30: note: expected ‘int *’ but argument is of type ‘int’
131 | int nombrepaireetimpaire(int tab[30], int k, int nb)
| ~~~~^~~~~~~
toto.c:233:36: warning: passing argument 1 of ‘moyennemaxetmin’ makes pointer from integer without a cast [-Wint-conversion]
233 | moyennemaxetmin(tab[30], k, max, moy, min, somme);
| ~~~^~~~
| |
| int
toto.c:162:25: note: expected ‘int *’ but argument is of type ‘int’
162 | int moyennemaxetmin(int tab[30], int k, int max, int moy, int min, int somme)
| ~~~~^~~~~~~


Vu que ton programme plante, c'est vraisemblablement une erreur de segmentation (c'est-à-dire que le programme essaye de lire à une adresse à laquelle il n'a pas le droit de lire). C'est typique dès qu'on utilise des pointeurs (et donc, des tableaux). Les nombreux warnings ci-dessus montrent que ta gestion actuelle des pointeurs est incorrecte.

Je t'invite donc à consulter un cours à ce sujet, notamment tout ce qui concerne le passage de tableau en paramètres de fonctions. Tu peux par exemple te baser sur cette discussion qui explique comment passer un tableau par pointeur.

Voici un exemple minimal comment passer une matrice (stocké sous forme d'un tableau de tableau de doubles) à une fonction :

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

double ** alloc_matrix(size_t m, size_t n) {
    double ** a = malloc(sizeof(double *) * m);
    for (size_t i = 0; i < m; i++) {
        a[i] = malloc(sizeof(double) * n);
    }   
    return a;
}

void free_matrix(double ** a, size_t m) {
    for (size_t i = 0; i < m; i++) {
        free(a[i]);
    }
    free(a);
}

void init_matrix(double ** a, size_t m, size_t n) {
    for (size_t i = 0; i < m; i++) { 
        for (size_t j = 0; j < n; j++) { 
            a[i][j] = 10 * i +  j;
        }
    }
}

void print_matrix(double ** a, size_t m, size_t n) {
    for (size_t i = 0; i < m; i++) { 
        for (size_t j = 0; j < n; j++) { 
            printf("%lf ", a[i][j]);
        }
        printf("\n");
    }
}   

int main(){
    const size_t m = 2;
    const size_t n = 2;
    double ** a = alloc_matrix(m, n);
    init_matrix(a, m, n);
    print_matrix(a, m, n);
    free_matrix(a, m);
    return 0;    
}


Ensuite, pour voir pourquoi (ou plutôt où) un programme a planté à cause d'une erreur de segmentation, le mieux est d'utiliser un débogueur, par exemple
gdb
. Si tu utilises un IDE (genre VisualStudio, DevC++, kdevelop ou anjuta) tu y as accès dans ton interface graphique.

Utilisation :

gcc -g -Wall toto.c -o tata
gdb ./tata


... puis dans gdb :

r


et quand le programme plante :

bt


Bonne chance
0