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 d'allocation mémoire dans un constructeur


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Problème d'allocation mémoire dans un constructeur
    Bonjour,

    Je suis débutant en programmation c++ et j'ai le problème suivant :
    J'ai une classe file (qui représente un automate) dans laquelle j'alloue deux map : une pour référencer les états (table_locations), et une pour référencer les transitions (table_edge).

    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
     
    class file {
    public:
    // 	used to parse fully the automaton in NBac format and make the product
     
    	declaration* declarations;
    	vector<definition*>* definitions;
    	vector<transition*>* transitions;
    	assertion_and_property_formula* assertion;
    	assertion_and_property_formula* initial;
    	assertion_and_property_formula* space;
    	assertion_and_property_formula* final;
    	control_structure* structure;
    	control_directive* directive;
     
    	map< pair<string, string>, edge* >* table_transitions;
    	map< string, location* >* table_etats;
     
    	file(){		declarations = NULL;
    		definitions = NULL;
    		assertion = NULL;
    		transitions = NULL;
    		initial = NULL;
    		space = NULL;
    		final = NULL;
    		structure = NULL;
    		directive = NULL;
    	};
    	file(declaration* d, vector<definition*>* def, vector<transition*>* t, assertion_and_property_formula* a, assertion_and_property_formula* i, assertion_and_property_formula* sp, assertion_and_property_formula* f, control_structure* s, control_directive* dir){
    		declarations = d;
    		definitions = def;
    		assertion = a;
    		transitions = t;
    		initial = i;
    		space = sp;
    		final = f;
    		structure = s;
    		directive = dir;
    	};
    	~file(){};
     
    	void preprocess();
    	void pretty(ostream* );
    };
    Une fois le fichier créé je le fais passer à travers une fonction preprocess qui remplit ces tables, et qui vérifie des propriétés sur les transitions :

    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
     
    void file::preprocess(){
     
    	vector<edge*>::iterator it2;
    	map< pair<string, string>, edge* >::iterator it;
    // 	cerr<<&table_transitions<<" "<<table_transitions.size()<<endl;
    	table_transitions = new map< pair<string, string>, edge* >();
    	table_etats = new map< string, location* >();
     
    	for(it2 = structure->edges->begin(); it2 != structure->edges->end(); it2++){
    		if(! table_transitions->empty()){
    			it = table_transitions->find(pair<string, string>((*it2)->origin, (*it2)->target));
    			if(it == table_transitions->end()){
    				table_transitions->insert(pair<pair<string, string>, edge*> (pair<string, string>((*it2)->origin, (*it2)->target), (*it2)));
    			}
    			else{
    	// 			TODO: tester si bug lors du erase...
    				((*it).second)->merge_edge_intern(*it2, new binop(binop::b_or));
    				structure->edges->erase(it2);
    				it2--;
    			}
    		}
    		else {
    			table_transitions->insert(pair<pair<string, string>, edge*> (pair<string, string>((*it2)->origin, (*it2)->target), (*it2)));
    		}
    	}
     
    	vector<location*>::iterator it3;
    	for(it3 = structure->locations->begin(); it3 != structure->locations->end(); it3++){
    		table_etats->insert(pair<string, location*>((*it3)->name, *it3));	
    	}
    }
    Tel quel le code marche mais quand j'alloue les tables dans le constructeur (par new map<...>() ) et non pas dans la fonction j'ai une segmentation fault. Il me semblait pourtant que les objets créés par new ne sont pas désalloués quand on sort de la fonction, puisqu'ils ne sont pas mis dans la pile d'appel, et comme je garde un pointeur vers cet objet je ne devrait pas en perdre la trace...

    Est-ce que quelqu'un peut me clarifier les idées la dessus ?

    Merci d'avance
    zaz83

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    L'astuce avec les classes, c'est que, comme pour les structures, les différents membres qui la composent sont accessibles tant qu'il existe un objet du type utilisé...

    Ainsi, tu n'a même pas besoin d'avoir recours aux pointeurs et de faire un new map <... , ...> dans ton constructeur, et c'est même pour le moins déconseillé (comme pour tous les conteneurs de la STL)

    En effet, le but même des différents conteneurs est de gérer l'allocation dynamique de manière tout à fait transparente pour toi, et sans doute de le faire bien mieux et de manière bien plus sécurisante que tout ce que tu pourrais faire par toi même...

    Au final, l'utilisation des pointeurs (sans s'intéresser à l'allocation dynamique) devrait être réservée au cas particulier où ta classe doit faire référence à un objet qui ne lui appartient pas et qui peut ne pas exister, ou dont la taille est supérieure ou égale à celle d'un objet de la classe qui dispose de cette référence(un pointeur sur le contenu dans le contenant, par exemple).

    Et l'allocation dynamique ne doit être utilisée que dans un cadre de polymorphisme si l'objet créé doit être renvoyé par la fonction qui le crée (ta fonction doit renvoyer un objet en le faisant passer pour un objet du type de base alors qu'elle crée un objet du type dérivé), ou si l'objet à créer doit avoir une durée de vie tout à fait indépendante de l'objet qui le crée.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Salut

    Finalement j'ai résolu le problème. J'ai suivi à moitié ton conseil : j'ai retiré tous les pointeurs sur les map. Le problème était tout bête : le makefile était fait de telle sorte que le fichier n'était pas recompilé si je ne modifiais que le header. D'ou tout un tas de problèmes

    merci beaucoup pour ta réponse et bonne journée
    zaz83/fruiten c++

Discussions similaires

  1. Problème d'allocation mémoire
    Par Fibus dans le forum GTK+ avec C & C++
    Réponses: 6
    Dernier message: 10/01/2008, 16h35
  2. Problème d'allocation mémoire
    Par elmayor1983 dans le forum C++
    Réponses: 5
    Dernier message: 14/02/2007, 10h08
  3. Problème d'allocation mémoire et fork
    Par Conap dans le forum Langage
    Réponses: 3
    Dernier message: 20/07/2006, 15h34
  4. Problème d'allocation mémoire
    Par araya dans le forum C
    Réponses: 2
    Dernier message: 04/05/2006, 20h03
  5. Problème d'allocation mémoire
    Par cali1983 dans le forum C++
    Réponses: 10
    Dernier message: 10/03/2006, 23h23

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