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 :

Violation de l'acces? comment est-ce possible?


Sujet :

C++

  1. #1
    Débutant
    Homme Profil pro
    aucun
    Inscrit en
    Avril 2012
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 152
    Points : 28
    Points
    28
    Par défaut Violation de l'acces? comment est-ce possible?
    Bonjour,

    Je suis débutant en c++ et je travailles avec les classes. J'ai eu une erreure grave. À chaque fois que j'execute le code. Il y a une alerte qui dit : violation d'acces lors de l'ouverture. Comment est-ce possible?

    wizard.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef WIZARD_H
    #define WIZARD_H
    #include <iostream>
    #include "latale.h"
     
    class wizard : public Personnage
    {
    public:
    	void sorc();
    };
    #endif
    warrior.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifndef WARRIOR_H
    #define WARRIOR_H
    #include <iostream>
    #include "latale.h"
     
    class warrior : public Personnage
    {
    public:
    	void bankai();
    };
     
    #endif
    latale.h
    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
    #ifndef LATALE_H
    #define LATALE_H
    #include <iostream>
    #include <string>
    #include "arme.h"
    #include "armure.h"
     
    class Personnage
    {
    private:
    	int hp;
    	int sp;
    	int xp;
    	int level;
    	double argent;
    	std::string nom;
    	std::string classe;
    	bool estVivant;
    	int force;
    	int rapidite;
    	int defense;
    	Arme *m_arme;
    	armure *m_armure;
     
    public:
    	Personnage();
    	int getForce() const;
    	int getRapidite() const;
    	void frapper(Personnage &cible);
    	int getDefense() const;
    	bool getVivant() const;
    	void faireFrapper(int arg1);
    	int getHp() const;
    	int getSp() const;
    	void execution();
    };
    #endif
    head.h
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    #include <iostream>
    #include <string>
    #include "latale.h"
    #include "warrior.h"
    #include "wizard.h"
     
    Personnage::Personnage()
    {
    	nom = "Ben";
    	hp = 100;
    	sp = 100;
    	xp = 0;
    	level = 0;
    	estVivant = true;
    }
     
    int Arme::getPuissance() const
    {
    	return puissance;
    }
     
    int Personnage::getForce() const
    {
    	int vitesse = getRapidite()/100;
    	return force+m_arme->getPuissance()+vitesse;
    }
     
    int Arme::getLeger() const
    {
    	return leger;
    }
     
    int armure::getProtection() const
    {
    	return protection;
    }
     
    int armure::getLourd() const
    {
    	return lourd;
    }
     
    int Personnage::getDefense() const
    {
    	return defense*m_armure->getProtection();
    }
     
    int Personnage::getRapidite() const
    {
    	return rapidite+m_arme->getLeger()-m_armure->getLourd();
    }
     
     
    armure::armure(string arg1,int arg2,int arg3)
    {
    	nom_armure = arg1;
    	protection = arg2;
    	lourd = arg3;
    }
     
    Arme::Arme(std::string arg1,int arg2, int arg3, int arg4)
    {
    	nom_arme = arg1;
    	puissance = arg2;
    	leger = arg3;
    	level_min = arg4;
    }
     
    bool Personnage::getVivant() const
    {
    	return estVivant;
    }
     
    int Personnage::getHp() const
    {
    	return hp;
    }
     
    int Personnage::getSp() const
    {
    	return sp;
    }
     
    void Personnage::faireFrapper(int arg1)
    {
    	if(hp > 0)
    	{
    		hp -= arg1;
    	}
    }
     
    void Personnage::execution()
    {
    	estVivant = false;
    }
     
    void Personnage::frapper(Personnage &cible)
    {
    	if(sp >= 5 && estVivant == true && cible.getVivant() == true)
    	{
    		int dommage = cible.getDefense()-getForce();
    		cible.faireFrapper(dommage);
    		if(cible.getHp() < 0)
    		{
    			execution();
    		}
    	}
    }
    arme.h
    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
    #ifndef ARME_H
    #define ARME_H
    #include <iostream>
    #include <string>
     
    class Arme
    {
    private:
    	std::string nom_arme;
    	int puissance;
    	int leger;
    	int level_min;
    public:
    	Arme(std::string arg1,int arg2, int arg3, int arg4);
    	int getPuissance() const;
    	int getLeger() const;
    };
    #endif
    armure.h
    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
    #ifndef ARMURE_H
    #define ARMURE_H
    #include <iostream>
    #include <string>
    using namespace std;
     
    class armure
    {
    private:
    	std::string nom_armure;
    	int protection;
    	int lourd;
    public:
    	armure(std::string arg1,int arg2,int arg3);
    	int getProtection() const;
    	int getLourd() const;
    };
     
    #endif
    trainning.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>
    #include <string>
    #include "head.h"
     
    using namespace std;
     
    int main()
    {
    	warrior ben;
    	wizard sam;
    	ben.frapper(sam);
    	return 0;
    }

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    Salut

    1. n'utilise pas de pointeurs nus (unique_ptr, shared_ptr)
    2. avant de faire un accès à un pointeur, toujours vérifier s'il est null
    3. as tu bien initialisé tes pointeurs ?
    4. donne des vrais noms à tes paramètres de fonction et pas arg1, arg2, etc

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

    Informations professionnelles :
    Activité : aucun

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

    Pour faire simple: parce qu'il y a énormément de place pour le progrès dans le code que tu présente

    D'abord, il y a quelques règles qu'il te faudrait suivre, uniquement pour te faciliter la vie (et la notre par la même occasion):
    1. Utiliser des noms de fichiers qui soient en rapport avec la classes qu'ils définissent : un fichier warrior.h(pp) et un fichier warrior.cpp seraient idéaux pour contenir la classe warrior (il en va évidemment de même pour toutes tes autres classes )
    2. Décider de règles de nommages qui seront respectées scrupuleusement dans tout le projet te faciliteront tout autant la vie: il n'est pas normal que warrior commence avec un w minuscule alors que Personnage commence par un P majuscule ( il en va aussi de même pour toutes tes classe) ou encore que tu aies, dans la même classe, des membre comme m_armure et hp...
    3. Le fait de donner des noms explicites à tes variables et à tes arguments permet de se faire une idée précise de leur utilité: avoir des arguments nommés arg1, arg2 et arg3 dans le constructeur de tes classes armes et armures ne nous indique pas à quoi ils servent, et, comme il y a deux (voir trois) entiers dans le lot, on a vite fait de passer l'un à la place de l'autre
    4. L'implémentation des fonctions se fait dans un fichier *.cpp, sauf exception (pour les fonctions implicitement ou explicitement inline)... jamais dans un fichier d'en-tête ( *.h ou *.hpp)
    5. Un fichier s'occupe d'une classe et d'une seule... C'est quoi cette idée de mélanger dans un seul fichier (d'en-tête qui plus est !!!! mais c'est peut etre header.cpp que tu voulais mettre comme nom :quesiton l'implémentation des fonctions propres de Arme, de Armure et de Personnage
    6. Si l'on peut estimer que certains attributs de ton personnage (comme hp, xp, sp ou level) peuvent effectivement être décidés de manière arbitraires, il est dommage d'obliger tous tes personnages à s'appeler "Ben"... il serait sans doute pas mal de passer un argument qui permette de définir le nom du personnage lors de sa création
    7. Pour le constructeur, justement, prends l'habitude de travailler avec les listes d'initialisation, tu ne t'en porteras que mieux
    8. Lorsque tu utilises des pointeurs "nus", penses à les définir à NULL (nullptr en C++11) si tu n'est pas en mesure de donner une adresse valide directement


    Maintenant, la réponse à ta question réelle...

    Les membres m_armure et m_arme sont tous deux des pointeurs, c'est à dire, des variables de type numérique qui représentent l'adresse à laquelle on est sensé trouver des objets de type arme (respectivement armure).

    Or, tu ne définis jamais une adresse valide pour ces deux membres!!!

    Du coup, par défaut, la valeur qu'ils prennent est (sans doute) NULL (ou nullptr), mais peut etre... strictement tout et n'importe quoi (les "crasses" résultant d'une utilisation antérieure de la mémoire).

    Du coup, tu n'as aucun moyen de savoir où le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_arme->getLeger()-m_armure->getLourd();
    va aller taper en mémoire, mais, une chose est sure, ce ne sera ni vers une arme, ni vers une armure

    Lorsque tu manipule des pointeurs, tu dois impérativement:
    1. veiller à les initialiser à NULL s'ils ne pointent sur aucun objet
    2. systématiquement vérifier que leur valeur n'est pas NULL avant toute tentative d'accès à "ce qui est pointé" par le pointeur
    N'oublies pas que toutes les variables que tu crées sont, par défaut, créées "sur la pile" et donc limitées, pour leur durée de vie, à la portée dans laquelle elles sont déclarée (sauf cas particulier où elles servent de retour de fonction).

    Si tu travailles avec des pointeurs, tu devras, plus que vraisemblablement, envisager de travailler avec de l'allocation dynamique de la mémoire, pour "prendre la main" sur la durée de vie de tes objets.

    Cela impliquera cependant que tu deviendras également responsable du fait qu'ils soient détruits "en temps et en heure"

    L'idéal est donc de préférence de travailler avec des pointeurs intelligents

  4. #4
    Membre éclairé

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Points : 877
    Points
    877
    Billets dans le blog
    1
    Par défaut
    Le polymorphisme nécessite la compréhension des classes.
    Ton fichier head.h devrait s'appeller head.cpp, voir ici.(Le nécessaire au c++)
    Et puis dans ce cas renomme le Personnage.cpp
    Du plus il ne doit être composé que de fonctions "type Personnage::Fonction(){}" (Personnage le nom de ton constructeur)
    Ton Arme::Arme(){} n'a rien à faire dans ton Personnage.cpp, il sera dans Arme.cpp

    "donne des vrais noms à tes paramètres de fonction et pas arg1, arg2, etc", tu peux par exemple nommer tes variables ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Arme::Arme(std::string nom_arme ,int puissance , int leger , int level_min)
    {
    	this->nom_arme = nom_arme;
    	this->puissance = puissance ;
    	this->leger = leger ;
    	this->level_min = level_min;
    }
    Et dans ton Arme.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Arme(std::string nom_arme ,int puissance , int leger , int level_min);
    [edit] Devancé... Je ne pense même pas que l'utilisation de pointeurs lui soit utile pour l'instant. (D'ailleurs à quel moment sont vraiment utile les pointeurs ? (le tri ?))

  5. #5
    Débutant
    Homme Profil pro
    aucun
    Inscrit en
    Avril 2012
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 152
    Points : 28
    Points
    28
    Par défaut
    Merci pour votre aide. ))

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur intermitente ! Comment est-ce possible ?
    Par shenzhu dans le forum Général Java
    Réponses: 6
    Dernier message: 17/05/2010, 21h18
  2. HashMap en multi-thread et NullPointerException ; comment est-ce possible ?
    Par sami44 dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 09/01/2008, 16h43
  3. Negociation, comment est ce possible?
    Par Jim_Nastiq dans le forum Paie
    Réponses: 11
    Dernier message: 31/07/2007, 17h03
  4. Comment est-ce possible ?
    Par Jibees dans le forum C
    Réponses: 25
    Dernier message: 05/09/2006, 12h08

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