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

Langage C++ Discussion :

Problème de pointeur null membre de classe


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 6
    Par défaut Problème de pointeur null membre de classe
    Bonjour,

    Je suis en train de faire le portage de mon code de visual 2003 à visual 2008. Après quelques modifications, la compilation s'est bien déroulé.
    Par contre des tests unitaires échouent. J'ai un problème assez étrange à vous faire part:
    J'ai une classe image dans laquelle se trouve quelques pointeurs initialisées à la construction.
    Dans le débugger la construction se déroule bien, mais lorsque l'on sort du contructeur et qu'on vérifie les membres de la classe, on s’aperçoit que les membres de type pointeur sont nulles (les autres variables membres sont normaux).
    Merci pour votre aide!

  2. #2
    screetch
    Invité(e)
    Par défaut
    un peu de code peut être?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 6
    Par défaut
    Voici le code concerné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    std::valarray<uint32_t> m_image;
    m_image.resize(nb_pix.x*nb_pix.y);
    uint32_t* image = &m_image[0];
    CImage<uint32_t> image_obj(image, nb_pix);
    Dans le contructeur de CImage, nous faisons :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T>
    CImage<T>::CImage(T* first_ptr, 
                      const uint2D& nb_pixels)
    :m_nb_pix(nb_pixels),
     m_data_ptr(first_ptr),
     m_has_acq_info(false),
     m_buffer_size(10),
     m_buffer(m_buffer_size)
    {
      m_mutex = new boost::mutex;
      m_test_ptr = new T;
    }
    Et dans le débugger nous avons dans le constructeur de CImage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    this	0x0012f1f0 {m_mutex=0x0205c050 m_acq_info={...} m_data_ptr=0x01ceb730 ...}	ImaOp::CImage<unsigned long> * const
    +		__vfptr	0x00be5198 const ImaOp::CImage<unsigned long>::`vftable'	*
    		m_mutex	0x0205c050	void *
    +		m_acq_info	{haso_serial_number=3435973836 length={...} exp_duration_us=-858993460 ...}	ImaOp::CImageInfo
    +		m_data_ptr	0x01ceb730	unsigned long *
    +		m_test_ptr	0x0205c098	unsigned long *
    		m_buffer_size	10	unsigned int
    +		m_buffer	[10](0,0,0,0,0,0,0,0,0,0)	std::vector<unsigned long,std::allocator<unsigned long> >
    +		m_nb_pix	{x=272 y=336 }	xy_pair<unsigned long>
    		m_has_acq_info	false	bool
    et a s'extérieur de celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    -		image_obj	{m_mutex=0xcccccccc m_acq_info={...} m_data_ptr=0xcccccccc ...}	ImaOp::CImage<unsigned long>
    +		__vfptr	0x00be5198 const ImaOp::CImage<unsigned long>::`vftable'	*
    		m_mutex	0xcccccccc	void *
    +		m_acq_info	{haso_serial_number=33931344 length={...} exp_duration_us=0 ...}	ImaOp::CImageInfo
    +		m_data_ptr	0xcccccccc	unsigned long *
    +		m_test_ptr	0xcccccccc	unsigned long *
    		m_buffer_size	3435973836	unsigned int
    		m_buffer	[4286484444](3452816845,...,...)	std::vector<unsigned long,std::allocator<unsigned long> >
    +		m_nb_pix	{x=3435973836 y=33931240 }	xy_pair<unsigned long>
    		m_has_acq_info	true	bool
    Contrairement en ce que j'ai dit plus haut, je m'aperçoit que le problème est "juste" la perte du pointeur CImage en sortant du contructeur. J'imagine que cela pourrait provenir d'un conflit entre lib header er dll?

  4. #4
    screetch
    Invité(e)
    Par défaut
    ou simplement que tu debugges un code optimisé, donc que les informations du debuggers peuvent ne pas être correctes?
    car a part ca je ne vois pas.
    sinon, c'est ou exactement "en dehors du destructeur"? un peu plus d'infos sur le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::valarray<uint32_t> m_image;
    m_image.resize(nb_pix.x*nb_pix.y);
    uint32_t* image = &m_image[0];
    CImage<uint32_t> image_obj(image, nb_pix);
    pourrait aider (il en fait quoi de image_obj?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 6
    Par défaut
    L'optimisation du code est bien désactivé pour la dll et les test unitaires.
    Par ailleurs les test unitaires passent tous avec le même code (modifié pour visual 2008) sous visual 2003 (j'ai dupliqué le même code dans deux répertoires différents pour évité des conflits entre les deux versions de visual)

    Enfin je m’aperçoit que le problème ne vient pas uniquement de mon objet CImage mais aussi du pointeur sur le valarray uint32_t* image
    Le test unitaire crash lorsque je rempli mon valarray en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     for (size_t k=0; k<6; k++)
            image[k+dep] = image[k+dep+10] = 0;
    Si l'on regarde au débugger les objets créés, on s’aperçoit que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                         std::valarray<uint32_t> m_image;
                         m_image.resize(nb_pix.x*nb_pix.y);
                         uint32_t* image = &m_image[0];
    a la ligne -->
    les objet m_image et image sont bien initialisé
    lorsque l'on ressort du contructeur de CImage ( donc après la ligne Image<uint32_t> image_obj(image, nb_pix);) le pointeur image n'a pas la même valeur et le débogeur ne peut plus lire le contenu de m_image

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Ca sent le buffer overrun.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     for (size_t k=0; k<6; k++)
            image[k+dep] = image[k+dep+10] = 0;
    Combien vaut dep ? Quelle est la taille de image (donc: combien valent nb_pix.x et nb_pix.y) ?
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par nanotech111 Voir le message
    Voici le code concerné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class T>
    CImage<T>::CImage(T* first_ptr, 
                      const uint2D& nb_pixels)
    :m_nb_pix(nb_pixels),
     m_data_ptr(first_ptr),
     m_has_acq_info(false),
     m_buffer_size(10),
     m_buffer(m_buffer_size)
    {
      m_mutex = new boost::mutex;
      m_test_ptr = new T;
    }
    Dangereux : le standard dit que les valeurs initialisées dans la liste d'initialisation le sont dans l'ordre de leur déclaration dans la classe, sans tenir compte de l'ordre dans lequel ils apparaissent dans la liste. Du coup, si m_buffer est déclaré avant m_buffer_size dans la classe, alors ce code va initialiser m_buffer avec une valeur inconnue.

    Normallement, les compilateurs détectent ce type de problème et t'avertissent ; si tu as bien déclaré les membres dans le bon ordre, ça ne posera pas de problèmes à court terme (par contre, si tu décides demain de changer l'ordre de déclaration, histoire de "faire plus propre" par exemple, tu risques de rencontrer des problèmes qui peuvent être potentiellement complexe à résoudre).

    Du coup, je te conseilles de modifier ce code de manière à ce que l'initialisation d'un membre ne dépendent pas des autres - dans ce cas, c'est facile puisque m_buffer_size est initialisé avec une constante.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. Problème de pointeur null avec Spring
    Par Psycho185 dans le forum Développement Web en Java
    Réponses: 2
    Dernier message: 13/09/2013, 20h04
  2. Déréférencement d'un pointeur null (dans une classe)
    Par polymorphisme dans le forum Langage
    Réponses: 5
    Dernier message: 13/09/2012, 15h44
  3. Problème de pointeur NULL ?
    Par foolib dans le forum C++
    Réponses: 9
    Dernier message: 18/09/2009, 10h42
  4. problème de pointeurs null
    Par blueLight dans le forum Langage
    Réponses: 3
    Dernier message: 04/08/2009, 20h05
  5. Réponses: 0
    Dernier message: 07/10/2008, 10h10

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