Archief - [PROG]C++ Segmentation fault (core dumped)

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

ng

Legacy Member
Goed, vandaag wat gewerkt aan een oefening voor m'n examen. Er staan geen fouten in (toch geen syntax fouten), maar als ik het laat runnen dan krijg ik dus de foutmelding die vermeld staat in de threadtitel.

de header file
Code:
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

#ifndef Persoon_h
#define Persoon_h

class Persoon
{
    public:
        enum Geslacht {MAN, VROUW};
    private:
        Geslacht mygeslacht;
        string myvoornaam;
        string myfamilienaam;
        Persoon* mymoeder;
        Persoon* myvader;
        Persoon** mykinderen;
        int mymax;

    public:
        Persoon (string voornaam= "", string familienaam="", Geslacht g = MAN);
        Persoon (const Persoon& p);
        ~Persoon ();
        string getVoornaam () const;
        void setVoornaam (string voornaam);
        string getFamilienaam () const;
        void setFamilienaam (string familienaam);
        int getMax () const;
        void setMax (int max);
        Geslacht getGeslacht () const;
        void setGeslacht (Geslacht g);
        void veranderVader (Persoon* M);
        void veranderMoeder (Persoon* V);
        void voegtoeKind (Persoon* K);
        void verwijderKind (Persoon* K);
        string toString () const;
};

#endif

en de cpp

Code:
#include "oefening12.h"

    Persoon::Persoon (string voornaam, string familienaam, Geslacht g)
    {
        myvoornaam = voornaam;
        myfamilienaam = familienaam;
        mygeslacht = g;
        mymax = 5;
        mykinderen = new Persoon* [mymax];
        for (int i=0; i<mymax; i++)
            mykinderen[i]=NULL;
    }

    Persoon::Persoon (const Persoon& p)
    {
        myvoornaam = p.getVoornaam ();
        myfamilienaam = p.getFamilienaam ();
        mymax = p.getMax ();
        mygeslacht = p.getGeslacht ();
    }

    Persoon::~Persoon ()
    {

    }

    string Persoon::getVoornaam () const
    {
        return myvoornaam;
    }

    void Persoon::setVoornaam (string voornaam)
    {
        myvoornaam = voornaam;
    }

    string Persoon::getFamilienaam () const
    {
        return myfamilienaam;
    }

    void Persoon::setFamilienaam (string familienaam)
    {
        myfamilienaam = familienaam;
    }

    int Persoon::getMax () const
    {
        return mymax;
    }

    void Persoon::setMax (int max)
    {
        mymax = max;
    }

    Persoon::Geslacht Persoon::getGeslacht () const
    {
        return mygeslacht;
    }

    void Persoon::setGeslacht (Geslacht g)
    {
        mygeslacht = g;
    }

    void Persoon::veranderVader (Persoon* M)
    {
        if (M->getGeslacht ()==MAN)
            myvader = M;
    }

    void Persoon::veranderMoeder (Persoon* V)
    {
        if (V->getGeslacht ()== VROUW)
            mymoeder = V;
    }

    void Persoon::voegtoeKind (Persoon* K)
    {
          for (int i=0; i<mymax; i++)
          {
            if (mykinderen[i] == NULL)
            {
                mykinderen[i] = K;

                i=mymax;
            }
          }
    }

   void Persoon::verwijderKind (Persoon* K)
   {
      for (int i=0; i<mymax; i++)
      {
           if (mykinderen[i] == K)
           {
                delete mykinderen[i];

                mykinderen[i]=NULL;
           }
        }
    }


    string Persoon::toString () const
    {
        stringstream ss;


        ss<<myvoornaam<<" "<<myfamilienaam<<endl;

        if (mymoeder->getVoornaam ()!=""||myvader->getFamilienaam ()!="")
        {
            if (mygeslacht == MAN)
                ss<<"Zoon van: ";
            else
                ss<<"Dochter van: ";
            if (mymoeder->getVoornaam ()!="")
                ss<<mymoeder->getVoornaam ()<<" "<<mymoeder->getFamilienaam ()<<" en ";
            if (myvader->getVoornaam ()!="")
                ss<<myvader->getVoornaam ()<<" "<<myvader->getFamilienaam ()<<endl;
        }

        if (mykinderen[0]!=NULL)
        {
           if (mygeslacht == MAN)
                ss<<"Vader van: ";
           else
                ss<<"Moeder van: ";
           for (int i=0; i<mymax; i++)
              ss<<mykinderen[i]->getVoornaam() <<" "<<mykinderen[i]->getFamilienaam()<<", ";
        }

        return ss.str ();
    }

int main ()
{
    Persoon* p1 = new Persoon ("William Henry", "Gates", Persoon::MAN);
    Persoon* p2 = new Persoon ("Kristanne", "Gates", Persoon::VROUW);
    Persoon* p3 = new Persoon ("Mary", "Maxwell", Persoon::VROUW);
    Persoon* p4 = new Persoon ("William Henry Jr.", "Gates", Persoon::MAN);
    Persoon* p5 = new Persoon ("William Henry Sr.", "Gates", Persoon::MAN);
    Persoon* p6 = new Persoon ("Lillian Elizabeth", "Rice", Persoon::VROUW);
    Persoon* p7 = new Persoon ("James Willard", "Maxwell", Persoon::MAN);
    Persoon* p8 = new Persoon ("Adele", "Thompson", Persoon::VROUW);

    p1->veranderMoeder (p3);
    p1->veranderVader (p4);
    p2->veranderMoeder (p3);
    p2->veranderVader (p4);
    p3->veranderMoeder (p8);
    p3->veranderVader (p7);
    p5->veranderVader (p4);
    p6->veranderVader (p4);

    delete [] p8;

    cout << p1->toString () << endl;
    cout << p2->toString () << endl;
    cout << p3->toString () << endl;
    cout << p4->toString () << endl;
    cout << p5->toString () << endl;
    cout << p6->toString () << endl;
    cout << p7->toString () << endl;

    cin.get ();

    return 0;
}

KeaTs

Legacy Member
p3 heeft als mymoeder p8
je delete p8
daarna in p3->toString roep je mymoeder->GetVoornaam() aan

that's a nono

same goes voor alle mensen waar je geen mymoeder en myvader gezet hebt, initialiseer die pointers op NULL en check ze op NULL voor je der functies op aanroept.

btw, mymoeder? :p Naming conventions ftw!

oh, en, run dat es in debug in een deftige compiler. Je moet een mooie debug msg krijgen die je precies zegt wat er scheelt ipv een segfault :)

forloRn_

Legacy Member
Kleine gok: je deletet p8 alsof het een array is, en de rest van de personen delete je niet. Oorzaken van segmentation faults opsporen doe je trouwens door je programma te compileren met debug-informatie en te runnen in valgrind.

Strings moet je trouwens ook by constant reference meegeven.

Therif

Legacy Member
moet er in de destructor normaalgezien dat niet in staan

delete[] mykinderen;


bij mij zegt em aan 't einde Bus Error

Xcode nog iets anders, heeft iets te maken met een van uw pointers die niet meer bereikbaar is op een of ander manier

Debugger geeft dit:

Code:
field _S_refcount is nonexistent or has been optimised out
field _S_synced_with_stdio is nonexistent or has been optimised out
Unexpected type (3) encountered for integer constant.
Unexpected type (3) encountered for integer constant.
Unexpected type (3) encountered for integer constant.
Unexpected type (3) encountered for integer constant.
Cannot access memory at address 0x0
Cannot access memory at address 0x0
Cannot access memory at address 0x0
Cannot access memory at address 0x0
Cannot access memory at address 0x0
Cannot access memory at address 0x0

Uw prog geraakt niet tot de destructor

Therif

Legacy Member
na een aantal testen heb 'k gemerkt dat de "core dumped" altijd komt van de toString functie...Maar de fout zelf vind 'k nie

killgore

Legacy Member
forloRn_ zei:
Kleine gok: je deletet p8 alsof het een array is, en de rest van de personen delete je niet. Oorzaken van segmentation faults opsporen doe je trouwens door je programma te compileren met debug-informatie en te runnen in valgrind.

Strings moet je trouwens ook by constant reference meegeven.

moeten nu niet echt niet, maar het is wel een sterke aanrader :p.

Voor de rest: segmentation of zo zien ligt vrijwel altijd aan geheugenmanagement, dus het is het beste dat je onmiddellijk gaat kijken naar je aanmaken, gebruik en vrijgeven van dynamisch geheugen. Nadat je natuurlijk via debuggen teweten bent gekomen waar de fout zich ongeveer voordoet.

Vooral dat gebruik eens nakijken vergeten vele mensen: vrijgegeven geheugen nog eens proberen aanroepen is a big nono.

Je leert die dingen wel als je wat segmentation & stack foutjes gekregen hebt.

Nog een leuke is out-of-bounds gaan bij statisch geheugen, dan krijg je ineens bad pointers en zo bij dingen waar dat helemaal niet kan :p.

ng

Legacy Member
En het werkt!

Na wat prutsen, met het advies hier gegeven, ben ik eropuit gekomen dat mijn if voorwaarden een beetje moesten herwerkt worden bij mij toString.


Bedankt voor alle hulp.

Therif

Legacy Member
kun je het antwoord eens posten?

want het blijkt dat jij ook op ehb zit :p


bedankt

Deguchi

Legacy Member
Hij crashte niet op u toString hoor, maar wel op u delete. Gebruik een deftige debugger en dan zult ge het sneller zien waar u probleem zit ;)

ng

Legacy Member
Voor Therif

de header file (onveranderd)

Code:
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

#ifndef Persoon_h
#define Persoon_h

class Persoon
{
    public:
        enum Geslacht {MAN, VROUW};
    private:
        Geslacht mygeslacht;
        string myvoornaam;
        string myfamilienaam;
        Persoon* mymoeder;
        Persoon* myvader;
        Persoon** mykinderen;
        int mymax;

    public:
        Persoon (string voornaam= "", string familienaam="", Geslacht g = MAN);
        Persoon (const Persoon& p);
        ~Persoon ();
        string getVoornaam () const;
        void setVoornaam (string voornaam);
        string getFamilienaam () const;
        void setFamilienaam (string familienaam);
        int getMax () const;
        void setMax (int max);
        Geslacht getGeslacht () const;
        void setGeslacht (Geslacht g);
        void veranderVader (Persoon* M);
        void veranderMoeder (Persoon* V);
        void voegtoeKind (Persoon* K);
        void verwijderKind (Persoon* K);
        string toString () const;
};

#endif

de cpp file

Code:
#include "oefening12.h"

    Persoon::Persoon (string voornaam, string familienaam, Geslacht g)
    {
        myvoornaam = voornaam;
        myfamilienaam = familienaam;
        mygeslacht = g;
        mymax = 5;
        mykinderen = new Persoon* [mymax];
        for (int i=0; i<mymax; i++)
            mykinderen[i]=NULL;
        myvader = NULL;
        mymoeder = NULL;
    }

    Persoon::Persoon (const Persoon& p)
    {
        myvoornaam = p.getVoornaam ();
        myfamilienaam = p.getFamilienaam ();
        mymax = p.getMax ();
        mygeslacht = p.getGeslacht ();
    }

    Persoon::~Persoon ()
    {

    }

    string Persoon::getVoornaam () const
    {
        return myvoornaam;
    }

    void Persoon::setVoornaam (string voornaam)
    {
        myvoornaam = voornaam;
    }

    string Persoon::getFamilienaam () const
    {
        return myfamilienaam;
    }

    void Persoon::setFamilienaam (string familienaam)
    {
        myfamilienaam = familienaam;
    }

    int Persoon::getMax () const
    {
        return mymax;
    }

    void Persoon::setMax (int max)
    {
        mymax = max;
    }

    Persoon::Geslacht Persoon::getGeslacht () const
    {
        return mygeslacht;
    }

    void Persoon::setGeslacht (Geslacht g)
    {
        mygeslacht = g;
    }

    void Persoon::veranderVader (Persoon* M)
    {
        if (myvader == NULL)
        {
            if (M->getGeslacht ()==MAN)
                myvader = M;
            else
                cout<<"verkeerd geslacht, wij doen geen operaties";
        }
        else
            cout<<"U hebt al een vader, u krijgt er geen twee";
    }

    void Persoon::veranderMoeder (Persoon* V)
    {
        if (mymoeder == NULL)
        {
            if (V->getGeslacht ()== VROUW)
                mymoeder = V;
            else
                cout<<"verkeerd geslacht, wij doen geen operaties";
        }
        else
            cout<<"U hebt al een moeder, u krijgt er geen twee";
    }

    void Persoon::voegtoeKind (Persoon* K)
    {
          for (int i=0; i<mymax; i++)
          {
            if (mykinderen[i] == NULL)
            {
                mykinderen[i] = K;
                i=mymax;
            }
          }
    }

   void Persoon::verwijderKind (Persoon* K)
   {
      for (int i=0; i<mymax; i++)
      {
           if (mykinderen[i] == K)
           {
                delete mykinderen[i];

                mykinderen[i]=NULL;
           }
        }
    }


    string Persoon::toString () const
    {
        stringstream ss;


        ss<<myvoornaam<<" "<<myfamilienaam<<endl;

        if (myvader!=NULL || mymoeder!=NULL)
        {
            if (mygeslacht == MAN)
                ss<<"Zoon van: ";
            else
                ss<<"Dochter van: ";
        }

        if (mymoeder!=NULL)
            ss<<mymoeder->getVoornaam ()<<" "<<mymoeder->getFamilienaam ()<<" en ";
        if (myvader!=NULL)
            ss<<myvader->getVoornaam ()<<" "<<myvader->getFamilienaam ()<<endl;


        if (mykinderen[0]!=NULL)
        {
           if (mygeslacht == MAN)
                ss<<"Vader van: ";
           else
                ss<<"Moeder van: ";
           for (int i=0; i<mymax; i++)
              if (mykinderen[i]!=NULL)
              {
                ss<<mykinderen[i]->getVoornaam() <<" "<<mykinderen[i]->getFamilienaam();
                if (mykinderen[i+1]!=NULL)
                    ss<<",";
              }
        }
        ss<<endl;
        return ss.str ();
    }

int main ()
{
    Persoon* p1 = new Persoon ("William Henry", "Gates", Persoon::MAN);
    Persoon* p2 = new Persoon ("Kristanne", "Gates", Persoon::VROUW);
    Persoon* p3 = new Persoon ("Mary", "Maxwell", Persoon::VROUW);
    Persoon* p4 = new Persoon ("William Henry Jr.", "Gates", Persoon::MAN);
    Persoon* p5 = new Persoon ("William Henry Sr.", "Gates", Persoon::MAN);
    Persoon* p6 = new Persoon ("Lillian Elizabeth", "Rice", Persoon::VROUW);
    Persoon* p7 = new Persoon ("James Willard", "Maxwell", Persoon::MAN);
    Persoon* p8 = new Persoon ("Adele", "Thompson", Persoon::VROUW);

    p1->veranderMoeder (p3);
    p1->veranderVader (p4);
    p3->voegtoeKind (p1);
    p4->voegtoeKind (p1);

    p2->veranderMoeder (p3);
    p2->veranderVader (p4);
    p3->voegtoeKind (p2);
    p4->voegtoeKind (p2);

    p3->veranderMoeder (p8);
    p3->veranderVader (p7);
    p8->voegtoeKind (p3);
    p7->voegtoeKind (p3);

    p5->veranderVader (p7);
    p7->voegtoeKind (p5);
    p6->veranderVader (p7);
    p7->voegtoeKind (p6);



    cout << p1->toString () << endl;
    cout << p2->toString () << endl;
    cout << p3->toString () << endl;
    cout << p4->toString () << endl;
    cout << p5->toString () << endl;
    cout << p6->toString () << endl;
    cout << p7->toString () << endl;

    cin.get ();

    return 0;
}

forloRn_

Legacy Member
Je zit met memory leaks. Dit wordt de destructor van Persoon:

Code:
Persoon::~Persoon ()
    {
	delete[] mykinderen;
    }

En dit zet je vóór of na de laatste cin.get() van je main():

Code:
delete p1;
delete p2;
delete p3;
delete p4;
delete p5;
delete p6;
delete p7;
delete p8;

En dan zegt valgrind:

Code:
==5651==
==5651== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==5651== malloc/free: in use at exit: 0 bytes in 0 blocks.
==5651== malloc/free: 46 allocs, 46 frees, 5,034 bytes allocated.
==5651== For counts of detected errors, rerun with: -v
==5651== No malloc'd blocks -- no leaks are possible.

:niceone:

ng

Legacy Member
Eigenlijk mag er aan die main niets veranderd worden.
Die is ons zo opgedragen.

Ow en die kinderen doe je niet zomaar weg, ze hebben ons altijd gezegd dat je eerst alle pointers in die array moet wegdoen. En dan pas de array zelf.

forloRn_

Legacy Member
Dat is een goede gewoonte, je memory leaks erin laten. :ironic:. Bovendien mag je die array zonder problemen deleten omdat je in je main toch beschikt over de pointers die in de array zitten.

Maar goed, je zal het wel beter weten.

ng

Legacy Member
Ik zeg gewoon hoe het ons is aangeleerd geweest.

Over die memory leaks heb je wel gelijk, maar de main functie is ons zo opgedragen geweest. Op een stuk papier, we mochten hem niet veranderen!

killgore

Legacy Member
Ik ken van die situaties, dat ze u vreselijk lompe interfaces of zo geven om mee te werken.

Wel, als ze comments lezen dan zullen de assistenten weten hoe ik over hen opgaves denk \o/

Tyfius

Legacy Member
Awel hè, het zou mij ten zeerste verbazen dat een docent als Van Laethem of Coninx zo'n dingen laten staan in een main() functie. Die kennen echt hun vak wel en zouden volgens mij nooit foute code opdragen.

edit: natuurlijk is dit niet echt fout-foute code, maar toch iets dat best vermeden wordt. Dit om misverstanden te vermijden :)

BartDP

Legacy Member
nja maar als dit gewoon een WC oefn is dan kijkt coninx die ni na tenzij ge erom vraagt
(dit was btw examenvraag vorig jaar alsek mij goed herriner)
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan