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

Dev-C++ Discussion :

[Dev-C++] Erreur de segmentation...


Sujet :

Dev-C++

  1. #1
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut [Dev-C++] Erreur de segmentation...
    bonjour � tous, j'ai un ch'ti probl�me avec une classe servant � lire/�crire dans des fichiers. Cette classe est contenu dans une dll et l'ensemble fonctionne bien sauf (�videment) une fonction membre....

    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
     
    void
    CFileIO::ReadWord(WORD *wBuf)
    {
        char *szBuf = NULL;
     
        szBuf = new char[sizeof(WORD) + 1]; 
        if ( szBuf )
        {
            memset(szBuf, 0, sizeof(WORD));
            m_iofile.read(szBuf, sizeof(WORD)); 
     
            memcpy(wBuf, szBuf, sizeof(WORD)); 
            *wBuf = INVW(*wBuf);
     
             delete [] szBuf;            
         }
    }        
     
    void
    CFileIO::ReadString(string &strBuf)
    {
           WORD SizeBuf;
           int iSize;
           char *szBuf = NULL;
     
            ReadWord(&SizeBuf);
            iSize = SizeBuf;
            szBuf = new char[iSize + 2];
            if ( szBuf )
            {           
                    memset(szBuf, 0, iSize + 1);                        
                    m_iofile.read(szBuf, iSize);
     
                    strBuf = szBuf;
            }
            delete [] szBuf;
    }
    La fonction ReadWord marche tr�s bien, je l'utilise ailleurs sans probl�me.

    Le hic c'est quand je debug avec gdb j'ai une erreur de segmentation
    sur une instruction du genre :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
     
        CFileIO myfile;
        string strString;
     
        '
        '  ici le code d'ouverture du fichier
        '
        myfile.ReadString(strString); // <- gdb me trouve un SIGSEGV
    Voyant la simplicit�e du code de la fonction ReadString je ne crois pas qu'il y est d'erreur. Alors dois-je chercher ailleurs dans mon code ?

    Ayant passer quelques temps la-dessus j'ai quelques questions qui me viennent :
    - dans 'szBuf = new char[iSize + 2];' le 'iSize' peut-etre de quel type (int, WORD, DWORD...) ?
    - cette instruction 'strBuf = szBuf;' fonctionne par copie ou non ?
    - y a-t-il une version C++ des fonctions 'memset' et 'memcpy' ?

    merci d'avance de vos r�ponses et bonne journ�e � tous

  2. #2
    Membre confirm�
    Inscrit en
    Avril 2002
    Messages
    180
    D�tails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 180
    Par d�faut
    Salut

    iSize est un int par convention (i)variable pour un int, (b)variable pour un bool, (sz)variable poue un string.....

    strBuf = szBuf
    STD::string::operator = fait effectivement une copy

    memset et memcpy ...
    memset: Il y a bien un ZeroMemory() mais je suis pas sur s'y il appartien au MFC ou a Windows oubien si il est standard??? de toute facon en C++ on utilise les constructeurs pour initialiser nos object

    memcpy: SL nous fourni un std::copy() mais dans quelle interet???

    je ne voit pas de probleme avec la methode ReadString
    Peut etre ajouter un test ;

  3. #3
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    je suis en train de r�-analyser mon code et j'ai trouver des new sans delete honte � moi... en corrigeant �a tout devrait rentrer en ordre...

    merci pour tes r�ponses (j'ai tendances � douter de mes acquis quand des crashs du genre surviennent, ha ces maudits memory-leaks que d'heures perdues � les d�nicher...), sinon existe-il des softs du style BoundCheckers mais adapter � Dev-C++ ???

  4. #4
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    bon je viens de trouver d'ou provenais l'erreur, par contre comprends pas pourquoi il y a cette erreur

    en fait mon code ReadString et ReadWord est bien OK, c'est dans le traitement du fichier qu'il y a un bug.

    voici le code que j'utilise pour acc�der au donn�es d'un fichier :

    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
     
    enum LOC { lcUNK=0, lcHDD, lcCD };
    typedef struct CATALOG_FILE
    {
        CATALOG_FILE()
        {
            data= new BYTE[DATASIZE + 2];
            memset(data, 0, DATASIZE + 1);
            Path = "?";
            Genre = "?";
            Titre = "?";
            loc = lcUNK;        
        }
        ~CATALOG_FILE()
        {
           delete [] data;
        }
     
        string Path;
        string Genre;
        string Titre;
        BYTE   *data;
        LOC    loc;
    };
    juste une petite question sur cette structure, avant de v�rifier mon code, j'utilisais juste cette forme l� :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct CATALOG_FILE
    {
        string Path;
        string Genre;
        string Titre;
        BYTE   data [DATASIZE];
        LOC    loc;
    };
    (�a bugger pareil), mais laquelle est le mieux ?

    voici comment j'acc�de au fichier :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        DWORD Count;
        long i;
     
        Cat.ReadDword(&Count);
        for (i = 0; i < Count; i++)
        {
            Cat.ReadString(cf.Path);
            Cat.Read(cf.data, DATASIZE);
     
            list.push_back(cf); << c là que ça plante
        }
    en fait 'list' est d�clar� comme �a : 'vector <CATALOG_FILE> list;'
    et apr�s quelques tours, l'�x�cution de 'list.push_back(cf)' fait changer subitement 'cf.data', ensuite le 'i' est incr�ment�, puis lors de l'�x�cution de 'Cat.ReadString(cf.Path);' �� crash, mais pourquoi ?? je croyais que le vector �tait s�curis� enfin qu'il ne pouvait pas arriver des trucs du genre....

    si qqn voit pkoi il y a un �crasement, des explications seraient les bienvenues car l� je ne capte pas.... merci

  5. #5
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Citation Envoy� par philippe V
    memset et memcpy ...
    memset: Il y a bien un ZeroMemory() mais je suis pas sur s'y il appartien au MFC ou a Windows oubien si il est standard??? de toute facon en C++ on utilise les constructeurs pour initialiser nos object
    Les �l�ments de la biblioth�ques standard sont tous en minuscules seulement, ou en majuscules seulement quand il s'agit de macros.
    Avec le C++, il y a std::fill_n. Ou les vecteurs (et autres containers) qui sont initialis�s avec le constructeur qui prend une taille => implicite

    Citation Envoy� par Philippe V
    memcpy: SL nous fourni un std::copy() mais dans quelle interet???
    Plusieurs:
    - Type-safe, pas besoin de faire des calculs savants avec sizeof
    - Pas de surcout pour les types de base, POD (je crois bien).
    - Appelle l'op�rateur d'affectation avec les objets. Objets qui ne peuvent et ne doivent en aucun cas �tre copi�s avec memcpy. Le r�sultat serait un comportement ind�fini.
    - Compatible avec une �criture it�rateurs. Bien quand on use et abuse de ceux-ci dans nos codes. Un peu moins adapt� quand on est � un bas niveau de communication et que l'on s�rialize et d�s�rialize dans des buffers d'octets.

    Ensuite, des remarques en vrac.
    - new est cens� renvoyer une exception sur les compilateurs � jour, pas null. (par d�faut VC6 nous oblige � faire des tests). Mais de toutes fa�ons, c'est inutile car ...
    - Pourquoi autant de copies dans readWord ? Il suffit de lire directement dans la variable POD.

    Perso, j'aurai tendance � �crire un simple :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    template <typename T>
    void Read(T & out) {
        m_iofile.read(reinterpret_cast<&out), sizeof(out));
        reorder(out); 
        // à écrire comme une spécialisation template qui dépendra de la machine cible, ...
    }
    - Les vecteurs ne s�curisent pas contre des mauvaises utilisation. La premi�re s�curit� est de ne pas perdre de m�moire en cas d'exception ou de retour hatif.

    - Le readString me semble un peu compliqu� -- des variables dupliqu�es, des pointeurs, d�clarations anticip�es des variables.
    J'ai plut�t tendance � partir dans cette direction:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template <> // spécialisation template
    void Read(std::string & out) {
        std::string::size_type size; // le seul vrai type taille pour les chaines
        Read(size);
        if (size) {
            std::vector v(size); // init inutile à 0
            m_iofile.read(&v[0], size);
            out.assign(v.begin(), v.end());
            // il y a deux copies difficiles à éviter avec std::string qui n'assure 
            // pas la consécutivité de ses éléments
        } else { 
            std::string().swap(out); // reset à rien de la chaine
        }
    }
    - la structure CATALOG_FILE, premi�re �criture, (sur le forum) n'est pas copiable � cause du pointeur brut. L'absence de contructeur de recopie et d'op�rateur d'affectation sp�cialis�s interdit toute copie, � cause du probl�me du double delete.
    Le plus simple est de n'utiliser que des attributs copiables. La copiabilit� de la classe englobante est alors assur�e par une sorte de transitivit�.

    Bien �videmment tu utilises un container (standard) de donn�es de type CATALOG_FILE. Or les containeurs standard exigent la copie-constructibilit� (copie via constructeur de recopie, qu'il soit d�fini explicitement, ou g�n�r� automatiquement par le compilo) pour les �l�ments stock�s. Ton type n'est pas copie constructible, donc ka-boum!

    La seconde �criture est copiable si LOC l'est. Les vecteurs peuvent s'av�rer mieux qu'un tampon � taille fixe. => base plus conviale.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  6. #6
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    merci pour toutes ces infos, je vois que t'as quelques ann�es d'exp�rience dans les doigts, par contre dans tes explications j'ai d�croch� � la derni�re partie (trop technique... )

    une question : 'reorder(out);' �� fait koi ???

    pour le ReadString que tu proposes...ben suis sur le cul... je savais pas que l'on pouvait faire : m_iofile.read(&v[0], size); comme si c'�tait un tableau de char !!! c'est sur que comme �� c plus simple !!!

    par contre est-ce normal comme d�claration :
    std::vector v(size); <-- y a pas le type du vector!!!
    ou un oubli et je devrais lire :
    std::vector <T>v(size);


    Pourrais-tu me dire dans quels cas il faut utiliser la copie de classe/structure ? vois pas trop bien pkoi dans le vector <CATALOG_FILE> �a plante...

    - la structure CATALOG_FILE, premi�re �criture, (sur le forum) n'est pas copiable � cause du pointeur brut. L'absence de contructeur de recopie et d'op�rateur d'affectation sp�cialis�s interdit toute copie, � cause du probl�me du double delete.
    Le plus simple est de n'utiliser que des attributs copiables. La copiabilit� de la classe englobante est alors assur�e par une sorte de transitivit�.

    Bien �videmment tu utilises un container (standard) de donn�es de type CATALOG_FILE. Or les containeurs standard exigent la copie-constructibilit� (copie via constructeur de recopie, qu'il soit d�fini explicitement, ou g�n�r� automatiquement par le compilo) pour les �l�ments stock�s. Ton type n'est pas copie constructible, donc ka-boum!

    La seconde �criture est copiable si LOC l'est. Les vecteurs peuvent s'av�rer mieux qu'un tampon � taille fixe. => base plus conviale.
    en fait c'est ici que j'ai d�croch�...donc si tu pourrais etre moins technique m'aiderait a comprendre....

  7. #7
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    J'ai en effet oubli� de pr�ciser le type des �l�ments du vecteur. Ici le but est de r�cup�rer un buffer d'octets. Soit, on va stocker des caract�res.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::vector<char> v(size);
    reorder() serait juste une fonction template � �crire et sp�cialiser soi-m�me. Le but est de corriger les probl�mes d'endianisme li�s aux s�rialisations "binaires" de nombres. C'�tait juste pour remplacer de fa�on g�n�rique le INVW.


    Sinon, ton probl�me est celui de la double lib�ration (delete[] dans ton cas) de la ressource (m�moire ici) brute (tu utilises un pointeur).
    Quand tu utilises push_back, une copie de l'�l�ment, pass� en param�tre, est r�alis�e au moment de le stocker dans le vecteur.

    Soit, cela revient � �crire:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    { 
        T t0; // que tu remplis...
        T t(t0);
    }
    Par d�faut le compilo g�n�re un constructeur de recopie qui fait appel aux constructeurs de recopie (ou assimil�) des attributs de ta classe T. Dans ton cas, un des attributs est un pointeur. Sa recopie est juste une recopie d'adresse.

    R�sultat, tu as t0 et t qui ont tous les deux un attribut de type de pointeur. Ces deux pointeurs ayant la m�me valeur (pointeur == adresse) apr�s recopie.

    Arriv� � l'accolade fermante, t0 et t sont d�truits. Dans les destructeurs, tu d�truis les variables point�es par tes pointeurs. En fait tu essaies de d�truire deux fois la m�me variable => boum.

    Je pense que cela doit �tre trait� dans une FAQ ou une autre. C'est un grand classique.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  8. #8
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    l� j'ai tout capt�, de plus je viens de lire quelques docs sur les constructeurs par copie... j'avais vu �a avec les templates mais pas fait le rapprochement.

    j'apprends le c++ d'une fa�on assez anarchique, je le reconnais, du coup je bloque pendant des heures sur des trucs tout con.... ben je vais me replonger dans mon code pour en mettre un peu partout de ces 'constructeurs par copie', il en a bien besoin.....


  9. #9
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Ils ne sont pas n�cessaires si tu construis tes classes autour d'attributs copiables (ou interdits de recopie) -- en fait, c'est la bonne technique (une r�gle simple (iste) pour ne pas faire n'importe quoi -> une classe de haut niveau ne devrait pas poss�der (g�rer en fait) de ressource brute, et en bas niveau ne pas en poss�der plus d'une (ressource brute))

    Ils ne sont n�cessaires qu'autour de ressources brutes (un vecteur, un smart-pointer, un fichier standard (non copiable en fait)... ne sont pas des ressources brutes). Et quand ils sont n�cessaires, alors l'op�rateur d'affectation l'est aussi.

    Il y a aussi la possibilit� de les interdire (la copie & l'affectation)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  10. #10
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    la m�thode du buffer avec un vector de char m'a beaucoup plus, mais par contre je s�che sur son adaptation avec des donn�es styles int, long, float....

    comment faire pour assigner/r�cup�rer ce genre de donn�es, utiliser le d�calage de bits pour chaque �l�ment du vector ?? Ou y a-t-il une solution plus simple ??

  11. #11
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Je ne suis pas s�r de comprendre ce que tu veux dire.
    Je me suis servi du vecteur de char comme d'un simple tampon (auto-lib�r� et -initialis�) pour r�cup�rer une donn�e (non n�c�ssairement formatt�) dont la taille n'�tait pas connue � la compilation.

    Les types de base se r�cup�rent directement sans passer par un tampon interm�diaire. C'est ce que fait la premi�re fonction template que j'avais donn�e.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  12. #12
    sas
    sas est d�connect�
    Membre �m�rite

    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    54
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 54
    Par d�faut
    Ben en fait dans une autre librairie de gestion de fichiers j'utilise un tampon de type BYTE pour lire/ecrire des donn�es, je place � la suite des unes des autres, des donn�es de type diff�rent (string, int, DWORD... enfin de tout type ) dans le tampon et j'�cris ce tampon dans un fichier (r�ciproquement pour la lecture).

    Ton buffer sous forme de vector m'a plu alors je voudrais adapter mon code pour qu'au lieu d'utiliser un tableau BYTE ce soit un vector de BYTE. Le hic c'est que, par exemple, pour un DWORD comment faire pour le 'loger' dans ce tampon. voici une proposition pour un string :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
        std::vector <BYTE> StreamBuf;
     
        for (int i = 0; i < strString.size())
            StreamBuf[m_PosCurrent + i] = (BYTE)strString[i];
    et pour un DWORD j'aurais fait :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
        std::vector <BYTE> StreamBuf;
     
        StreamBuf[m_PosCurrent] = ((dwValue << 24) >> 24);
        StreamBuf[m_PosCurrent + 1] = ((dwValue << 16) >> 24);
        StreamBuf[m_PosCurrent + 2] = ((dwValue << 8) >> 24);
        StreamBuf[m_PosCurrent + 3] = (dwValue >> 24);
    et dans le m�me style

    Mais vois-tu une autre solution plus int�ressante ?

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    R�ponses: 16
    Dernier message: 18/10/2005, 11h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    R�ponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    R�ponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-Cpp] Erreur "Macro Names Must be Identifiers"
    Par TheRedLed dans le forum Dev-C++
    R�ponses: 6
    Dernier message: 07/06/2005, 20h12
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    R�ponses: 10
    Dernier message: 15/03/2005, 11h18

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