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

SL & STL C++ Discussion :

Erreur de segmentation sur ifstream.close()


Sujet :

SL & STL C++

  1. #1
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 64
    Points : 170
    Points
    170
    Par défaut Erreur de segmentation sur ifstream.close()
    Bonjour,

    Je rencontre un problème pour la création d'une méthode de lecture dans un fichier.
    j'utilise un pointeur de ifstream déclaré et initialisé dans la méthode, puis je fais un open sur mon fichier en mode texte. Cette partie fonctionne très bien.
    Ensuite, je ferme mon fichier pour pouvoir le ré-ouvrir en mode binaire. Je me replace là ou je m'étais arrêté en mode texte et je lis des entiers. La lecture se passe très bien aussi.

    Mais l'erreur se trouve lorsque je re-ferme le ifstream (que ce soit avec close(), le destructeur ou rien du tout (destruction automatique des variables à la fin de la méthode)). Lors de l'exécution, j'ai une erreur de segmentation !! :'(

    voici le résultat de backtrace dans gdb :

    << : (0.742781,3.24967,-0)
    === Test 1 ===
    test

    Program received signal SIGSEGV, Segmentation fault.
    0xb7d25e68 in _int_free () from /lib/tls/i686/cmov/libc.so.6
    (gdb) bt
    #0 0xb7d25e68 in _int_free () from /lib/tls/i686/cmov/libc.so.6
    #1 0xb7d26456 in free () from /lib/tls/i686/cmov/libc.so.6
    #2 0xb7f020b1 in operator delete () from /usr/lib/libstdc++.so.6
    #3 0xb7f0210d in operator delete[] () from /usr/lib/libstdc++.so.6
    #4 0xb7ea888f in std::basic_filebuf<char, std::char_traits<char> >::_M_destroy_internal_buffer () from /usr/lib/libstdc++.so.6
    #5 0xb7ea9e01 in std::basic_filebuf<char, std::char_traits<char> >::close ()
    from /usr/lib/libstdc++.so.6
    #6 0xb7eab355 in std::basic_ifstream<char, std::char_traits<char> >::close ()
    from /usr/lib/libstdc++.so.6
    #7 0x0804b579 in Image::fromFile (this=0xbfd6e1a0, filename=
    {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xbfd6de6c "\024�k\b"}}) at Image.cpp:192

    #8 0x0804bc2c in Image (this=0xbfd6e1a0, filename=
    {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xbfd6e1d0 "\024�k\b��\004\b��ֿ"}}) at Image.cpp:15
    #9 0x0804a6a4 in main () at main.cpp:124
    (gdb)

    et le code de ma méthode (avec le header de la classe) :

    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
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    #ifndef IMAGE_H
    #define IMAGE_H
    
    #include <string>
    using namespace std;
    
    
    class Image {
    public:
        struct pixel {
            unsigned short r;
            unsigned short g;
            unsigned short b;
        };
        // Exceptions
        class OutOfRangeException {};
    private:
        pixel *m_pix;
        int m_width, m_height;
        string m_filename;
        //fstream * m_file;
    public:
        Image (int width, int height);
        Image (string filename);
        Image (const Image & src);
        ~Image ();
        
        
        int getWidth () const;
        int getHeight () const;
        pixel getPixel (int x, int y) const;
        
        void setPixel (int x, int y, pixel p);
        void setPixelRow (int y, pixel row[]);
        void setPixelColumn (int x, pixel col[]);
        
        void toFile (string filename) const;
        void fromFile (string filename);
        
        const Image & operator= (const Image & src);
        
        bool operator== (const Image & p) const;
        bool operator!= (const Image & p) const;
    };
    
    #endif
    
    
    
    //==================================================================
    void Image::fromFile (string filename) {
        // Ouverture du fichier
        ifstream * m_file = new ifstream();
        m_file->open(filename.c_str(), ios_base::in);
        if (!m_file) {
            //cerr << "Ouverture impossible de " << filename << endl;
            return;
        }
        
        // Variables de lecture
        char byte;
        unsigned short dbyte;
        unsigned short maxcolor;
        
        // Magic number
        *m_file >> byte;
        if (byte != 'P')
            return;
        *m_file >> byte;
        if (byte != '6')
            return;
        
        // Width
        *m_file >> dbyte;
        if (dbyte <= 0)
            return;
        m_width = dbyte;
        
        // Height
        *m_file >> dbyte;
        if (dbyte <= 0)
            return;
        m_height = dbyte;
        
        // Max color
        *m_file >> dbyte;
        if (dbyte <= 0)
            return;
        maxcolor = dbyte;
        
        // Init pixel map
        m_pix = new pixel[m_width*m_height];
        
        // Ouverture en mode binaire
        int position = m_file->tellg();
        
        m_file->close();
        delete m_file;
        
        m_file = new ifstream();
        m_file->open(filename.c_str(), ios_base::in|ios_base::binary);
        if (!m_file) {
            //cerr << "Ouverture binaire impossible de " << filename << endl;
            return;
        }
        m_file->seekg(position+1, ios::beg);    // skips single whitespace
        
        // Pixels
        for (int x=0; x<m_height; x++) {
            for (int y=0; y<m_width; y++) {
                if (maxcolor < 256) {   // Couleur sur 1 octet
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].r)), 1);
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].g)), 1);
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].b)), 1);
                }
                else {  // couleur sur 2 octets
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].r)), 2);
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].g)), 2);
                    m_file->read(reinterpret_cast<char *>(&(m_pix[ x + m_width*y ].b)), 2);
                }
            }
        }
        
        cerr << "test" << endl;
        
        m_file->close();
        delete m_file;
    }
    Ah oui et je pense pas que ca change quoi que ce soit, mais cette méthode je l'appelle aussi depuis un constructeur (c'est ce que j'utilise pour faire le test).

    Merci.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Pourquoi t'utilises de l'allocation dynamique ?
    Essaie avec le mode debug de ta bibliothèque standard, accessoirement.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour,
    Sans compter qu'à chaque fois que tu es en erreur, tu fais un return sans delete sur le pointeur.
    Petite question : Que vaut m_pix[ x + m_width*y ] aux limites ? C'est à dire quand x et y atteignent la borne supérieure du for ? Ca devrait expliquer des choses...

  4. #4
    Membre habitué
    Inscrit en
    Novembre 2004
    Messages
    64
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 64
    Points : 170
    Points
    170
    Par défaut
    Rebonjour,
    merci pour vos réponses.

    Pour l'allocation dynamique c'était un essai, mais même sans le problème est le même.

    Citation Envoyé par 3DArchi Voir le message
    Bonjour,
    Sans compter qu'à chaque fois que tu es en erreur, tu fais un return sans delete sur le pointeur.
    Petite question : Que vaut m_pix[ x + m_width*y ] aux limites ? C'est à dire quand x et y atteignent la borne supérieure du for ? Ca devrait expliquer des choses...
    les return dans les cas d'erreur c'est en attendant mieux, mais tout se déroule comme il faut donc là ca pose pas de problème particulier.
    pour m_pix[ x + m_width*y ] c'est une structure qui contient 3 couleurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct pixel {
            unsigned short r;
            unsigned short g;
            unsigned short b;
        };
    pour les limites, m_pix[ x + m_width*y ].......

    Eh mais j'avais un problème dans ma boucle !!!
    merci c'est bon l'erreur est partie je marque résolu


    par contre ce que je comprend pas c'est pourquoi j'avais l'erreur de segmentation dans le close() du fichier ?!

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par tHE_fLAmMinG_mOE Voir le message
    par contre ce que je comprend pas c'est pourquoi j'avais l'erreur de segmentation dans le close() du fichier ?!
    Les conséquences d'un écrasement mémoire sont imprévisibles

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 15/07/2010, 17h01
  2. erreur de segmentation sur affectation champ enum structure
    Par marion5515 dans le forum Débuter
    Réponses: 9
    Dernier message: 24/02/2010, 11h51
  3. Erreur de segmentation sur une concaténation
    Par cypher.sephiroth dans le forum Débuter
    Réponses: 14
    Dernier message: 18/08/2009, 17h42
  4. Erreur de segmentation sur une File
    Par hugo1992 dans le forum C
    Réponses: 2
    Dernier message: 22/10/2007, 08h49
  5. Erreur de segmentation sur une chaine en récursif...
    Par laurent_ifips dans le forum C
    Réponses: 12
    Dernier message: 13/12/2005, 16h04

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