Langage C: problème de segmentation fault
Fermé
Sportif_C
-
4 juin 2011 à 23:40
mamiemando Messages postés 33363 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 novembre 2024 - 7 juin 2011 à 00:31
mamiemando Messages postés 33363 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 novembre 2024 - 7 juin 2011 à 00:31
A voir également:
- Langage C: problème de segmentation fault
- Langage ascii - Guide
- Langage binaire - Guide
- Pascal langage - Télécharger - Édition & Programmation
- Langage pascal - Télécharger - Édition & Programmation
- Débuter langage batch windows - Guide
7 réponses
ljm972
Messages postés
254
Date d'inscription
vendredi 23 février 2007
Statut
Membre
Dernière intervention
6 décembre 2021
29
5 juin 2011 à 02:17
5 juin 2011 à 02:17
Bonjour, cela dépend de CreationTournee();
A l'appel de cette function,
est-ce que DistanceEntreVertex est un tableau à 2 dimensions ?
A l'appel de cette function,
est-ce que DistanceEntreVertex est un tableau à 2 dimensions ?
Merci pour ta réponse.
Oui. C'est un tableau de 2D .
Voici le main
Oui. C'est un tableau de 2D .
Voici le main
int main() { GestionVertex LaGestion ; double **DistanceEntreVertex = CalculDistance(&LaGestion); CreationTournee (&LaGestion, DistanceEntreVertex, &CapCamion); return 0; }
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 841
5 juin 2011 à 12:39
5 juin 2011 à 12:39
Oui. C'est un tableau de 2D .
As-tu bien pensé à réaliser l'allocation dynamique ? Est-ce bien dans la fonction CalculDistance() ?
As-tu bien pensé à réaliser l'allocation dynamique ? Est-ce bien dans la fonction CalculDistance() ?
Oui.
Voici ma fonction CalculDsitance
Voici ma fonction CalculDsitance
typedef struct Vertex Vertex; struct Vertex { int no; double x; double y; int demand; int service_time; int lower; int upper; int capacity; int start_time; }; /* cette strucutre n'est pas indispensable, mais fourni une aide */ typedef struct GestionVertex GestionVertex; struct GestionVertex { int NombreVertex; Vertex *Tableau; /* Ce tableau a pour but de faciliter la recuperation des données lors de l'evaluation de la tournee */ double **DistanceEntreVertex; }; double **CalculDistance(GestionVertex *LaGestion) { if ((LaGestion->DistanceEntreVertex = malloc (24 * sizeof(double*))) == NULL) { perror("Erreur lors du malloc sur LaGestion->DistanceEntreVertex dans la fonction CreationGestionVertex"); exit (EXIT_FAILURE); } int i,j; for (i=0 ; i<24 ; i++) if ((LaGestion->DistanceEntreVertex[i] = malloc (24 * sizeof(double))) == NULL) { perror("Erreur lors du malloc sur LaGestion->DistanceEntreVertex dans la fonction CreationGestionVertex "); exit (EXIT_FAILURE); } for (i=0 ; i< 24 ; i++) { /* Cette case ne devrait jamais etre lu, mais par precaution */ LaGestion->DistanceEntreVertex[i][i] = 0.0; for (j=0 ; j<i ; j++) LaGestion->DistanceEntreVertex[i][j] = LaGestion->DistanceEntreVertex[j][i] = sqrt(pow((LaGestion->Tableau[i].x - LaGestion->Tableau[j].x),2.0) + pow((LaGestion->Tableau[i].y - LaGestion->Tableau[j].y),2.0)); } return LaGestion->DistanceEntreVertex; }
mamiemando
Messages postés
33363
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
16 novembre 2024
7 801
5 juin 2011 à 12:55
5 juin 2011 à 12:55
La ligne à laquelle ça plante laisse penser que soit DistanceEntreVertex n'est pas alloué (ou i est trop grand), ou bien DistanceEntreVertex[i] n'est pas alloué (ou j est trop grand).
La première chose à faire c'est de vérifier les valeurs que i et j prennent juste avant cette ligne avec ton debugger ou un printf. Si les valeurs sont "cohérentes" par rapport à ton algorithme, c'est probablement que tu t'es planté dans l'allocation (ou que tu as oublié de la faire).
Supposons que DistanceEntreVertex soit une matrice de taille m x n, l'allocation devrait se faire ainsi :
Attention également à la désallocation, à faire dans cet ordre. Je te rappelle que des outils comme valgrind permettent de détecter les fuites mémoire :
Sinon j'ai quelques conseils à te proposer, à prendre ou pas selon ta motivations ;-)
1) Dans les conventions c/c++, seules les classes commencent par une majuscule (et encore certains utilisent ce_genre_de_notation). Ainsi tu devrais écrire :
2) Le mix anglais français n'est pas toujours très heureux. De plus ton DistanceEntreVertex (ce serait Vertices en plus :p) symbolise un graphe donc autant l'appeler "distanceGraph" par exemple...
3) Évite les constantes en dures (genre 23 et 24), mets par exemple un #define ou un paramètre pour rendre ton code plus lisible / générique / maintenable.
4) Je pense que tu n'as pas écrit ce que tu voulais ici :
5) Utilise firefox (oups ça n'a rien à voir :p)
Bonne chance
La première chose à faire c'est de vérifier les valeurs que i et j prennent juste avant cette ligne avec ton debugger ou un printf. Si les valeurs sont "cohérentes" par rapport à ton algorithme, c'est probablement que tu t'es planté dans l'allocation (ou que tu as oublié de la faire).
Supposons que DistanceEntreVertex soit une matrice de taille m x n, l'allocation devrait se faire ainsi :
int i; DistanceEntreVertex = (double **) malloc(sizeof(double *) * m); for(i = 0; i < m; ++i) { DistanceEntreVertex[i] = (double *) malloc(sizeof(double ) * n); // Si tu veux que les cases soient initialisées à 0 tu peux écrire : // DistanceEntreVertex[i] = (double *) calloc(sizeof(double ), n); }
Attention également à la désallocation, à faire dans cet ordre. Je te rappelle que des outils comme valgrind permettent de détecter les fuites mémoire :
for(i = 0; i < m; ++i) { free(DistanceEntreVertex[i]); } free(DistanceEntreVertex);
Sinon j'ai quelques conseils à te proposer, à prendre ou pas selon ta motivations ;-)
1) Dans les conventions c/c++, seules les classes commencent par une majuscule (et encore certains utilisent ce_genre_de_notation). Ainsi tu devrais écrire :
struct MaStructure{ double **monMembreDeStructure; }; void maFonction(); class MaClasse { protected: double ** monMembreDeClasse; public: MaClasse() {} void maMethode(); };
2) Le mix anglais français n'est pas toujours très heureux. De plus ton DistanceEntreVertex (ce serait Vertices en plus :p) symbolise un graphe donc autant l'appeler "distanceGraph" par exemple...
3) Évite les constantes en dures (genre 23 et 24), mets par exemple un #define ou un paramètre pour rendre ton code plus lisible / générique / maintenable.
4) Je pense que tu n'as pas écrit ce que tu voulais ici :
recommence == 1;
5) Utilise firefox (oups ça n'a rien à voir :p)
Bonne chance
Merci pour ces conseils. J'en tiens compte après la correction du programme.
J'ai une question SVP: Est ce que je fais la désallocation à l'intérieur de la fonction où j'ai déclaré mon tableau de 2D?
Je remis encore une fois mes deux fonctions qui nous intéresse. Pourriez-vous me dire ce que vous avez compris du role de la fonction CreationTournee?
Merci de votre aide.
J'ai une question SVP: Est ce que je fais la désallocation à l'intérieur de la fonction où j'ai déclaré mon tableau de 2D?
Je remis encore une fois mes deux fonctions qui nous intéresse. Pourriez-vous me dire ce que vous avez compris du role de la fonction CreationTournee?
Merci de votre aide.
typedef struct Tournee Tournee; struct Tournee { int *Tableau; double DistanceTotal; }; //Solution note le tableau de tournees typedef struct Solution Solution; struct Solution { int *indCamions; //indice camionpour indiquer lindice de la tournee dans le tableau de tournees Tournee *Tableau; double distance; }; typedef struct Vertex Vertex; struct Vertex { int no; double x; double y; int demand; int service_time; int lower; int upper; int capacity; int start_time; }; /* cette strucutre n'est pas indispensable, mais fourni une aide */ typedef struct GestionVertex GestionVertex; struct GestionVertex { int NombreVertex; Vertex *Tableau; /* Ce tableau a pour but de faciliter la recuperation des données lors de l'evaluation de la tournee */ double **DistanceEntreVertex; }; double **CalculDistance(GestionVertex *LaGestion) { if ((LaGestion->DistanceEntreVertex = malloc (24 * sizeof(double*))) == NULL) { perror("Erreur lors du malloc sur LaGestion->DistanceEntreVertex dans la fonction CreationGestionVertex"); exit (EXIT_FAILURE); } int i,j; for (i=0 ; i<24 ; i++) if ((LaGestion->DistanceEntreVertex[i] = malloc (24 * sizeof(double))) == NULL) { perror("Erreur lors du malloc sur LaGestion->DistanceEntreVertex dans la fonction CreationGestionVertex "); exit (EXIT_FAILURE); } for (i=0 ; i< 24 ; i++) { /* Cette case ne devrait jamais etre lu, mais par precaution */ LaGestion->DistanceEntreVertex[i][i] = 0.0; for (j=0 ; j<i ; j++) LaGestion->DistanceEntreVertex[i][j] = LaGestion->DistanceEntreVertex[j][i] = sqrt(pow((LaGestion->Tableau[i].x - LaGestion->Tableau[j].x),2.0) + pow((LaGestion->Tableau[i].y - LaGestion->Tableau[j].y),2.0)); } return LaGestion->DistanceEntreVertex; } Tournee CreationTournee (GestionVertex *GestionVertex, double **DistanceEntreVertex, int CapCamion) { srand (time (NULL)); Tournee Tournee; Solution ptr; Tournee.Tableau = malloc(24*sizeof(Tournee)); GestionVertex->Tableau = malloc(24*sizeof(GestionVertex)); ptr.Tableau = malloc(24*sizeof(ptr)); ptr.indCamions= malloc(24*sizeof(ptr)); int i; int j; for (i=0; i < 23; i++) Tournee.Tableau[i] = -1; double demandeTot = 0; for (i=0; i < 23; i++) demandeTot += GestionVertex->Tableau[i].demand; double Distancemax = 0; printf("%d\n", i); printf("%d", j); for (i=0; i < 24; i++) { for(j=i+1; j<24; j++) { if ( Distancemax < DistanceEntreVertex[i][j]) Distancemax = DistanceEntreVertex[i][j]; } } printf("je suis ici"); //creation des routes en prennant a chaque fois le vertex suivant le plus proche int random; int tmp = 0; int VertexDepart = 0; int CapaciteCamion = CapCamion; int position = 0; int recommence; Tournee.Tableau[0] = 0; for ( i= 0; i < 24; i++) { if ( i != 0 ) VertexDepart = Tournee.Tableau[i-1]; recommence == 1; while(recommence) { recommence == 0; //Creer la tournee entierement aleatoirement //recherche de la prochaine ville la plus proche est non deja deservie tmp = TourneeRechercheVertexPlusProche(VertexDepart, DistanceEntreVertex, Tournee); for (j=0; j<i; j++) if (tmp == Tournee.Tableau[j]) recommence == 1; } int CapaTmp = CapaciteCamion - GestionVertex->Tableau[tmp].demand; if ( (tmp = aleatoire(0, 24) ) && CapaTmp >= 0 && position > 6 )//6: taille de tournee { ptr.indCamions[i] = 1; CapaciteCamion = CapCamion; CapaciteCamion -= GestionVertex->Tableau[tmp].demand; position = 0; if ( i != (24-2) )//24: nbre de vertex ptr.Tableau[i+1]; } else { if ( CapaTmp >= 0 ) { CapaciteCamion -= GestionVertex->Tableau[tmp].demand; if ( i == (24-2) ) { ptr.indCamions[i] = 1; } else ptr.indCamions[i] = 0; } else if ( CapaTmp < 0 ) { ptr.indCamions[i-1] = 1; ptr.Tableau[i]; if ( i == (24-2) ) { ptr.indCamions[i] = 1; } else ptr.indCamions[i] = 0; CapaciteCamion = CapCamion; CapaciteCamion -= GestionVertex->Tableau[tmp].demand; position = 1; } } Tournee.Tableau[i]=tmp; position++; } }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mamiemando
Messages postés
33363
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
16 novembre 2024
7 801
5 juin 2011 à 15:41
5 juin 2011 à 15:41
Bah pour j on a clairement unproblème :-)
Pour l'allocation il faut t'inspirer de ce qui est fait en langage objet avec les concepts de constructeurs et de destructeurs. Une "fonction" appelée constructeur est dédiée à l'allocation (et éventuellement l'initialisation), une autre à la désallocation.
Par exemple si j'écris une structure matrice en langage C voici à quoi ça ressemblerait :
Pour l'allocation il faut t'inspirer de ce qui est fait en langage objet avec les concepts de constructeurs et de destructeurs. Une "fonction" appelée constructeur est dédiée à l'allocation (et éventuellement l'initialisation), une autre à la désallocation.
Par exemple si j'écris une structure matrice en langage C voici à quoi ça ressemblerait :
#include <stdlib.h> #include <assert.h> typedef struct matrix_t { size_t num_rows; size_t num_cols; double **data; } matrix_t; inline matrix_t *alloc_matrix(size_t num_rows, size_t num_cols) { size_t i; matrix.num_rows = num_rows; matrix.num_cols = num_cols; matrix.data = (double **) malloc(sizeof(double *) * m); for(i = 0; i < m; ++i) { matrix.data[i] = (double *) calloc(sizeof(double ), n); } return matrix; } inline void free_matrix(matrix_t *matrix) ' size_t i; for(i = 0; i < m; ++i) { free(matrix.data[i]); } free(matrix.data); } inline size_t get_num_rows(const matrix_t *matrix) { return matrix.num_rows; } inline size_t get_num_cols(const matrix_t *matrix) { return matrix.num_cols; } inline size_t get_value(const matrix_t *matrix, size_t i, size_t j) { assert(i < get_num_rows(matrix)); assert(j < get_num_cols(matrix)); return matrix.data[i][j]; } inline size_t set_value(matrix_t *matrix, size_t i, size_t j, double value) { assert(i < get_num_rows(matrix)); assert(j < get_num_cols(matrix)); matrix.data[i][j] = value; } inline void write_matrix(const matrix_t *matrix) { size_t i, j; for(i = 0; i < get_num_rows(matrix); ++i) { for(j = 0; j < get_num_cols(matrix); ++j) { printf("%lf\t", get_value(matrix, i, j); } printf("\n"); } } int main(){ matrix_t *matrix = alloc_matrix(5,4); write_matrix(matrix); free_matrix(matrix); return 0; }
Merci pour ta réponse.
Apperement le problème vient du l'oubli de l'astérics (*) lors de la déclaration de la fonction CreationTournee. Le problème de plantage est disparu.
Maintenant, j'aimerais savoir si le corps de ma fonction est cohérent (l'usage de while, des variable booléenne, etc). J'ai fais l'appel de ces fonctions dans le main. Lors de l'exécution, j'ai rien obtenu. Je l'ai commenté pour que tu peux comprendre ce que je cherche à faire.
Merci encore pour ton aide.
Je reposte la dernière version de mon code.
Apperement le problème vient du l'oubli de l'astérics (*) lors de la déclaration de la fonction CreationTournee. Le problème de plantage est disparu.
Maintenant, j'aimerais savoir si le corps de ma fonction est cohérent (l'usage de while, des variable booléenne, etc). J'ai fais l'appel de ces fonctions dans le main. Lors de l'exécution, j'ai rien obtenu. Je l'ai commenté pour que tu peux comprendre ce que je cherche à faire.
Merci encore pour ton aide.
Je reposte la dernière version de mon code.
//la tournee ici est un tableau de client à livrer typedef struct Tournee Tournee; struct Tournee { int *Tableau; double DistanceTotal; }; //Solution note le tableau de tournees typedef struct Solution Solution; struct Solution { int *indCamions; //indice camionpour indiquer lindice de la tournee dans le tableau de tournees Tournee *Tableau; double distance; }; typedef struct Vertex Vertex; struct Vertex { int no; double x; double y; int demand; int service_time; int lower; int upper; int capacity; int start_time; }; /* cette strucutre n'est pas indispensable, mais fourni une aide */ typedef struct GestionVertex GestionVertex; struct GestionVertex { int NombreVertex; Vertex *Tableau; /* Ce tableau a pour but de faciliter la recuperation des données lors de l'evaluation de la tournee */ double **DistanceEntreVertex; }; /* * Creation d'une tournee respectant les contraintes * soit la tournee est cree en cherchant a chaque fois la ville la plus proche * soit on peut creer la tournee de maniere aleatoire**/ int aleatoire(int max, int min) //fonction permet de générer des valeurs aléatoires compris entre min et max { return (min + (rand () % (max-min+1))); } Tournee *CreationTournee (GestionVertex *GestionVertex, double **DistanceEntreVertex, int CapCamion) { srand (time (NULL)); Tournee Tournee; Solution ptr; Tournee.Tableau = malloc(24*sizeof(Tournee)); GestionVertex->Tableau = malloc(24*sizeof(GestionVertex)); ptr.Tableau = malloc(24*sizeof(ptr)); ptr.indCamions= malloc(24*sizeof(ptr)); int i; int j; for (i=0; i < 23; i++) Tournee.Tableau[i] = -1; double demandeTot = 0; for (i=0; i < 23; i++) demandeTot += GestionVertex->Tableau[i].demand; double Distancemax = 0; printf("%d\n", i); printf("%d", j); for (i=0; i < 24; i++) { for(j=i+1; j<24; j++) { if ( Distancemax < DistanceEntreVertex[i][j]) Distancemax = DistanceEntreVertex[i][j]; } } //creation des routes en prennant a chaque fois le vertex suivant le plus proche int random; int tmp = 0; int VertexDepart = 0; int CapaciteCamion = CapCamion; int position = 0; int recommence; Tournee.Tableau[0] = 0; for ( i= 0; i < 24; i++) { if ( i != 0 ) VertexDepart = Tournee.Tableau[i-1]; recommence == 1; while(recommence) { recommence == 0; //Creer la tournee entierement aleatoirement //recherche de la prochaine ville la plus proche est non deja deservie tmp = TourneeRechercheVertexPlusProche(VertexDepart, DistanceEntreVertex, Tournee); for (j=0; j<i; j++) if (tmp == Tournee.Tableau[j]) recommence == 1; } int CapaTmp = CapaciteCamion - GestionVertex->Tableau[tmp].demand; if ( (tmp = aleatoire(0, 24) ) && CapaTmp >= 0 && position > 6 )//6: taille de tournee { ptr.indCamions[i] = 1; CapaciteCamion = CapCamion; CapaciteCamion -= GestionVertex->Tableau[tmp].demand; position = 0; if ( i != (24-2) )//24: nbre de vertex ptr.Tableau[i+1]; } else { if ( CapaTmp >= 0 ) { CapaciteCamion -= GestionVertex->Tableau[tmp].demand; if ( i == (24-2) ) { ptr.indCamions[i] = 1; } else ptr.indCamions[i] = 0; } else if ( CapaTmp < 0 ) { ptr.indCamions[i-1] = 1; ptr.Tableau[i]; if ( i == (24-2) ) { ptr.indCamions[i] = 1; } else ptr.indCamions[i] = 0; CapaciteCamion = CapCamion; CapaciteCamion -= GestionVertex->Tableau[tmp].demand; position = 1; } } Tournee.Tableau[i]=tmp; position++; } } /* * Renvoie le numero du vertex le plus proche de v_depart */ int TourneeRechercheVertexPlusProche(int Vertexdepart, double** DistanceEntreVertex, int *TableauDejaUtilise) { double DistanceMin = INFINI; int continuer = 1; int trouve = 0; int i; int j; int Vertexproche = 0; for (i=1; i < 24; i++) { continuer == 1; for (j=0; j < 24 - 1; j++) { if ( i == TableauDejaUtilise[j] ) trouve == 1; } if ( (i != Vertexdepart) ) { if (DistanceEntreVertex[Vertexdepart][i] < DistanceMin ) { trouve == 1; Vertexproche = i; DistanceMin = DistanceEntreVertex[Vertexdepart][i] ; } } } return Vertexproche; } /*Affiche la tournee mais ajoute aussi l'affichage de la demande totale de chaque tournee * ainsi que la capacite des camions disponible*/ void TourneeAffichage(int CapaciteCamion) { Solution Solution; Tournee Tournee; GestionVertex GestionVertex; int i; printf("Solution : " ); for (i=0; i < (24 -1); i++) printf("%i %d",i, Solution.indCamions[i] ) ; printf("Tournee : " ); for (i=0; i < (24-1); i++) printf("%d", Tournee.Tableau[i]) ; printf("Tableau Tournees: "); for(i=0; i < 5; i++) // 5: nbre camions printf("%d",Solution.Tableau[i]); double Demande = 0; int Tourn = 1; int Prem = 0; int respect = 1; printf( "Capacite d'un camion : "); for (i=0; i < (24-1); i++) { if (Solution. indCamions[i] == 0 ) { if ( Demande == 0 ) Prem = i; Demande += GestionVertex.Tableau[i].demand; } else { Demande += GestionVertex.Tableau[i].demand; if (Demande > CapaciteCamion ) respect = 0; printf( "Tournee num : %d de prem %d a %d demande --> %d", Tourn, Prem, i, Demande); Tourn++; Demande = 0; } } if ( !respect ) printf("Attention -> ici : Non respect de la contrainte demande ! "); else printf("Tout va bien ici la contrainte de demande est respectee :-) ! " ); }
mamiemando
Messages postés
33363
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
16 novembre 2024
7 801
7 juin 2011 à 00:31
7 juin 2011 à 00:31
Ok, avais-tu d'autres question ou ton problème est résolu ?