Je rencontre une erreur lors de l'execution du programme suivant , j'ai pu constaté que la fonction qui cause l'erreur a l’exécution est la fonction afiicherTransistion (dans transition.h && transition.cpp).
Je ne sais pas quel est exactement la raison de segmentation fault .
#ifndef AUTOMATE_H
#define AUTOMATE_H
#include "transition.h"
#include "Etat.h"
#include <stdlib.h>
#include <vector>
#include <iostream>
/* Automate représenté sous forme de quintuplet
A = alphabet
Q = enseble des etats
D = ensemble etats de dédepart
F = ensemble des etats etatsFinaux
T = ensembleDesTransitions
*/
class Automate{
private:
char alphabet[5]={'a','b','c','d','e'};
std::vector<Etat> ensembleGlobal;
std::vector<Etat*> etatsFinaux;
std::vector<Etat*> etatsInitiaux;
std::vector<Transition> ensembleTransitions;
public:
Automate();
Automate(int nbSalles);
Etat transitionnement(const Etat &n, char a); // passe d'un etat donné a l'état le liant par l'etiquette de la fonction de transition
void ajouterNouvelleTransition(int indiceDepart, int indiceArivee, char a);// ajoute une nouvelle transition a l'ensemle des transitions
void afficherTransitionIndice(int n);// affiche la transition a l'indice n
void afficherEnsembleTransitions(); // affiche l'ensemle des transitions
};
#endif
automate.cpp
#include "automate.h"
using namespace std;
Automate::Automate(){};
Automate::Automate(int nbSalles){
string a ="";
for(int i=0;i<ensembleGlobal.size();i++){
a = to_string(i);
ensembleGlobal[i]=Etat(a);
}
}
Etat Automate::transitionnement(const Etat &n,char a){ // passe de l'etat actuel a un etat suivant si il y a une etiquette corresponddant a A se renvoi lui même sinon
for (int i = 0 ;i<ensembleTransitions.size();i++){
if(&n == ensembleTransitions[i].getEtatDepart() && a == ensembleTransitions[i].getEtiquette()){
return *ensembleTransitions[i].getEtatArivee();
}
}
}
void Automate::ajouterNouvelleTransition(int indiceDepart, int indiceArivee, char a){
Transition t(&ensembleGlobal[indiceDepart],&ensembleGlobal[indiceArivee],a);
ensembleTransitions.push_back(t);
}
void Automate::afficherEnsembleTransitions(){
for(int i=0;i<ensembleTransitions.size();i++){
ensembleTransitions[i].afficherTransition();
}
}
void Automate::afficherTransitionIndice(int n){
ensembleTransitions.at(n).afficherTransition();
}
Les erreurs de segmentation (Segmentation fault) sont causées par l'accès à un endroit de la mémoire qui ne t'appartient pas. Cela peut être le déférencement du pointeur NULL, l'utilisation d'un pointeur après delete ou le fait de sortir d'un tableau.
Il faut bien noter que par défaut les std::vector sont vides. Ainsi, si dans ta classe Automate tu n'augmentes pas la taille de 'ensembleGlobal', cette dernière restera à 0. Et justement, tu n'augmentes jamais la taille de ce dernier. Ainsi, quelque soit les indices que tu passes à la fonction 'ajouterNouvelleTransition', '&ensembleGlobal[indice]' est en dehors du tableau: tu accèdes donc à de la mémoire de n'appartenant pas lorsque tu essayes d'utiliser la variable 'depart' de ta classe 'Transition' ce qui cause l'erreur de segmentation.
Je n'ai pas regardé en détail le code (cela implique que le correctif proposé n'a peut être pas de sens pour l'utilisation que tu veux, cependant il en a dans le contexte du constructeur), mais, en changeant le constructeur de Automate comme suivant, la sortie est (et sans erreur de segmentation):
Execution
0a1
1c3
Automate::Automate(int nbSalles){
string a ="";
for(int i=0;i<nbSalles;i++){ //ensembleGlobal.size() vaut 0 et donc tu ne rentrais jamais dans cette boucle
a = to_string(i);
ensembleGlobal.emplace_back(a); //ensembleGlobal[i]=Etat(a); Aurait causer une erreur de segmentation.
//emplace_back augmente la taille du tableau tout comme push_back le fait,
//la différence étant que emplace_back ne crée pas de copie supplémentaire
//de l'objet à insérer
}
}
Je m'excuses pour les éventuelles fautes d'orthographe.
ici ton constructeur attend deux pointeur du type Etat (EtatDepart et etatArivee) mais toi, tu initialise très mal tes attribut (depart et arrivee) qui sont de pointeurs et aussi des objet du type Etat; or pour initialiser un objet qui est un pointeur on utilise l'opérateur " new ".
Certes... Mais on utilise pas toujours nes pour modifier un pointeur (meme un pointeur vers un objet) et la facon (sans new) dont il gere son constructeur semble correcte.
J'ai l'impression que tu confond allouer un espace memoire et initialiser un pointeur...
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C