2010-12-10 5 views
2

Voici un exemple de code pour illustrer le problème que je rencontre.C++ Héritage Problème: problème de segmentation

#include <iostream> 

using namespace std; 

class Foo 
{ 
    public: 
     Foo(int x) 
     { m_x = x; } 
     int getX() 
     { return m_x; } 
    private: 
     int m_x; 
}; 

class Bar : public Foo 
{ 
    public: 
     Bar(int x) : Foo(x) 
     {} 
     //some other stuff 
}; 

int main() 
{ 
    Bar* bar = new Bar(5); 
    cout<<bar->getX()<<endl; 
    return 0; 
} 

J'ai un grand projet sur lequel je travaille et j'ai une situation similaire à ci-dessus. Lorsque bar-> getX() est appelé, ce pointeur est 0x0 provoquant une erreur de segmentation. J'ai essayé de copier la fonction getX à la classe Bar, mais cela ne résout pas le problème, le pointeur this est toujours 0x0. Des idées? Je n'ai aucune idée de comment google pour cela, seulement trouvé des gens ayant des problèmes avec des fonctions virtuelles.

ps. Cet exemple fonctionne.

EDIT:

std::cout<<m_engine<<std::endl; 
focus_x = m_engine->getX(); 

La sortie est: 0x2e6d763638667858 (non NULL), de sorte que ce n'est pas le problème ...

+2

J'ai regardé le code en essayant de trouver un problème, puis j'ai remarqué votre commentaire au bas de cet exemple de travail. Ce sera plus facile si vous postez le code qui ne fonctionne pas, et nous pouvons vous aider à comprendre le problème. – LeopardSkinPillBoxHat

+0

cela pourrait se produire seulement si 'nouveau' échoue ET vous utilisez en quelque sorte la version non lancante du nouveau – Chubsdad

+0

@ Chubsdad - pour 'nouveau' échouer dans l'exemple ci-dessus, vous devez utiliser un ordinateur avec * très * limité Ressources. – LeopardSkinPillBoxHat

Répondre

1

Mon estimation, à partir de votre édition, est que m_engine est un pointeur qui pend.

En d'autres termes, la mémoire pointée par m_engine a été delete d. Vous avez toujours l'adresse où la mémoire a été allouée stockée dans m_engine, mais lorsque vous essayez d'accéder à cette adresse en mémoire en attendant un Foo valide, Bar, objet objet d'être là, cette partie de la mémoire a été récupérée par le fonctionnement système et un autre objet utilise éventuellement cette mémoire.

L'accès à la mémoire qui a été désaffectée est un comportement indéfini en C++.

Je vous suggère d'ajouter un point d'arrêt dans le destructeur m_engine (quelle que soit la classe) pour voir qui supprime m_engine.

L'autre possibilité est la corruption de la mémoire, mais cela est beaucoup plus difficile à diagnostiquer.

+0

Ou, 'm_engine' n'a jamais été initialisé, ou c'est un membre d'un objet qui a été supprimé. (Ce sont toutes les versions du même problème sous-jacent, mais pour un nouveau venu, cela peut être difficile à voir.) –

+0

@Dan Breslau - si 'm_engine' n'a pas été initialisé, j'aurais pensé qu'il aurait eu un modèle plus prévisible comme '0xcdcdcdcd' dedans (bien que je fasse des suppositions au sujet du compilateur et du système d'exploitation). – LeopardSkinPillBoxHat

+0

C'est une mauvaise hypothèse; MS Studio est le seul compilateur que je connaisse qui initialise la mémoire comme ça, et il ne le fait qu'en mode debug. Mais puisque nous ne connaissons pas le code, j'ajouterai qu'il est possible que 'm_engine' soit accédé par un pointeur initialisé à quelque chose comme 0xDEADBEEFBAADFOOD, qui pourrait pointer vers la mémoire qui se trouve avoir 0x2e6d763638667858 à cet endroit. Peu probable, mais possible. –

0

Lorsque le pointeur est this 0x0, cela signifie que vous avez appelé un membre fonctionner sur un pointeur NULL. Vous devrez retracer votre code et comprendre comment le pointeur d'objet est devenu NULL. Il n'y a pas assez dans votre exemple de code pour diagnostiquer le problème.

+0

Oui, et appeler une fonction membre avec un tel pointeur est un comportement indéfini. – Chubsdad

+0

std :: cout << m_engine << std :: endl; focus_x = m_engine-> getX(); La sortie est: 0x2e6d763638667858 (pas NULL), donc ce n'est pas le problème ... – papodaca

+0

@ Chubsdad, indéfini ne signifie pas toujours imprévisible. Les compilateurs traditionnels implémentent souvent des constructions communes de la même manière, et il est possible de deviner et/ou d'apprendre ces fonctionnements internes. –