Zugriffsverletzung (Segmentation fault)



  • Mein Programm stürzt leider beim ausführen immer wieder ab, dies liegt lt. Debugger an einem Sementation fault.

    Bei folgendem Quellcode:

    vector<complex<double> > ua = readComplexNumbers(filename,"dep","U_ME1.v");
        vector<double> uq = readValues(filename,"indep","uq");
        vector<double> un(uqs);
        double var = phases*frequencies;
    
        for(size_t i = 0; i != uqs;++i){
                   complex<double> uvar = (0,0);
                   for(size_t j = (i*var); j != ((i+1)*var);++j){                       
                                 uvar += ua[j];          
                   }                              
                   un[i] = abs(uvar / var);
        }
    

    sorgt die Zeile:

    uvar += ua[j];
    

    für die Zugriffsverletzung. Nur verstehe ich nicht genau warum?! bzw. wie ich das beheben kann...


  • Mod

    Dann wird ua wohl kein Element mit der Nummer j haben. Vergleich doch mal j mit der Größe von ua.



  • SeppJ schrieb:

    Dann wird ua wohl kein Element mit der Nummer j haben. Vergleich doch mal j mit der Größe von ua.

    ua hat genau [uqs*var] Elemente. Es sind in diesem Beispiel insgesamt 163613 Elemente. Beim testen mit 100 Elemten gab es keinen Fehler...



  • Javun schrieb:

    ua hat genau [uqs*var] Elemente. Es sind in diesem Beispiel insgesamt 163613 Elemente. Beim testen mit 100 Elemten gab es keinen Fehler...

    Das kann nicht beides wahr sein. 163613 ist eine Primzahl.



  • seldon schrieb:

    Javun schrieb:

    ua hat genau [uqs*var] Elemente. Es sind in diesem Beispiel insgesamt 163613 Elemente. Beim testen mit 100 Elemten gab es keinen Fehler...

    Das kann nicht beides wahr sein. 163613 ist eine Primzahl.

    😃 +1 👍



  • seldon schrieb:

    Das kann nicht beides wahr sein. 163613 ist eine Primzahl.

    <kluschiß>
    Wenn entweder uqs oder var 1 ist schon.
    </klugschiß>



  • 163613 ist die max. Größe des Arrays, also ist array[163613] der letzte Wert im Array, da aber in array[0] auch ein Wert enthalten ist, gibt es insgesamt 163614 Werte.

    Das ist genau die Menge an Elementen, die das Array auch haben soll. Leider gibt es trotzdem diesen Fehler und ich weiß immer noch nicht warum...

    Wie bereits erwähnt gibt es komischer Weise bei kleineren Werten also Array Größe ca. unter 1000 keinen Fehler.



  • Nein, bei ein Array a mit 10 Elementen wird mit a[9] auf das letzte Element zugegriffen.



  • knivil schrieb:

    Nein, bei ein Array a mit 10 Elementen wird mit a[9] auf das letzte Element zugegriffen.

    Und was steht bei mir anderes?!

    Ich hab geschrieben das das Array b[163613] 163614 Elemente hat. Ich habe mich also verschrieben und vorhin statt 163614, 163613 geschrieben.

    Das ist jedoch nicht die Frage oder Lösung meines Problemes...



  • Javun schrieb:

    Ich hab geschrieben das das Array b[163613] 163614 Elemente hat.

    Das hast du eben nicht geschrieben. Vergleich:

    163613 ist die max. Größe des Arrays

    D.h. es kann maximal 163613 Elemente aufnehmen. Da mit 0 angefangen wird zu indexieren, ist der letzte Index um eins kleiner als die die Groesse. D.h. der letzte Wert im Array ist b[163612]. Groesse != letzter Index



  • Gut... Mit Größe meine ich das max. was in den [...] steht. Hab ich mich vllt. falsch ausgedrückt.

    An meinem Problem ändert das leider nichts...

    Also nochmal von Vorne:
    Größe des Array: 163614
    Anzahl der Werte: 163614

    Letzter ausgelesener Index in der Schleife 163613! Also muss der Segmentation fault eine andere Ursache haben...



  • Hallo Javun,

    Letzter ausgelesener Index in der Schleife 163613

    Laut Deinem Code ist der letzte Index 163614

    vector<double> un(uqs); 
        for(size_t i = 0; i != uqs;++i)
    

    Richtig wäre:

    vector<double> un(uqs); 
        for(size_t i = 0; i < uqs;++i)
    

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    vector<double> un(uqs); 
        for(size_t i = 0; i != uqs;++i)
    

    Richtig wäre:

    vector<double> un(uqs); 
        for(size_t i = 0; i < uqs;++i)
    

    Kommt beides exakt aufs gleiche raus.



  • Javun schrieb:

    complex<double> uvar = (0,0);
    

    uvar wird zwar 0 sein, das liegt aber an der 0 hinter dem Komma.
    Der Ausdruck (0,0) ist äquivalent zu 0
    Der Ausdruck (2,0) ist äquivalent zu 0
    Der Ausdruck (0,3) ist äquivalent zu 3
    Der Ausdruck (5,7) ist äquivalent zu 7
    Siehst Du hier ein Muster?
    Das, was Du schreiben wolltest war:

    complex<double> uvar (0,0);
    

    Dies ist eine direkte Initialisierung und die Nullen sind hier Konstruktorparameter.
    Oder Du wolltest vielleicht das hier schreiben:

    complex<double> uvar = complex<double>(0,0);
    

    Javun schrieb:

    sorgt die Zeile:

    uvar += ua[j];
    

    für die Zugriffsverletzung.

    Klingt nach ungültigem Index j, der außerhalb des zulälssigen Bereichs ist.

    Schau mal in der Doku Deines Compilers nach, ob sich bei der Standardbibliothek ein Debug-Modus aktivieren lässt. Bei G++/libstdc++ gibt es so'was, das weiß ich.



  • Hallo LordJaxom,

    Kommt beides exakt aufs gleiche raus.

    Uups, hast Recht.

    Wobei ich die Notation

    i != uqs
    

    in einer for Schleife mindestens "ungewöhlich" finde.

    Herzliche Grüsse
    Walter



  • weicher schrieb:

    Hallo LordJaxom,

    Kommt beides exakt aufs gleiche raus.

    Uups, hast Recht.

    Wobei ich die Notation

    i != uqs
    

    in einer for Schleife mindestens "ungewöhlich" finde.

    Herzliche Grüsse
    Walter

    Dann bist Du einfach nicht auf dem neuesten Stand.

    Man schreibt ja gerne ++i statt i++, um nicht darüber nachdenken zu müssen, ob i jetzt ein eingebauter Typ ist oder ein selbergebauter. ++i ist auf allen Typen effizient, während i++ da durchaus denkbare Performanceprobleme haben könnte.

    Aus dem gleichen Grund schreibt man i!=uqs statt i<uqs. Man stelle sich zum Beispiel Iteratoren auf verkettete Listen vor. != geht instant, wärend < nur in O(Abstand) geht. Es wäre denkbar, daß der op< mal sehr schnarchig ist, während der op!= immer schnell ist. != ist also theoretisch vielleicht manchmal besser. Ach, eigentlich nicht. Wer einen lahmen op< hätte, bietet den op< besser gar nicht an. Mit != zeigt man, daß man cool ist. Und doch, man muß nicht darüber nachdenken, ob der op< angeboten wird.



  • Hallo Volkard,

    Dann bist Du einfach nicht auf dem neuesten Stand.

    Das ist gut möglich, auch in anderen Bereichen als C++ 😃

    Aber ist der (i != x) Ausdruck nicht auch potentiell gefährlich? Wenn innerhalb der Schleife jemand i auf x + 1 stellt (Natürlich nicht so offensichtlich)erlebt er eine Überaschung.

    Herzliche Grüsse
    Walter


  • Mod

    weicher schrieb:

    Aber ist der (i != x) Ausdruck nicht auch potentiell gefährlich? Wenn innerhalb der Schleife jemand i auf x + 1 stellt (Natürlich nicht so offensichtlich)erlebt er eine Überaschung.

    Wer wäre denn dieser jemand? Doch wohl der Programmierer der Schleife selbst. Und beim allerersten Test fällt's auf.



  • Hallo Sepp,

    SCNR

    Und beim allerersten Test fällt's auf.

    Eventuell weil es dann eine Zugriffsverletzung gibt? 😉

    Herzliche Grüsse
    Walter


  • Mod

    weicher schrieb:

    Eventuell weil es dann eine Zugriffsverletzung gibt? 😉

    Ja, beispielsweise 👍 .

    Und dann gibt es eben die Programmierer die den Debugger benutzen können und das Problem damit sofort erkennen, diejenigen die Debugausgaben selber schreiben und ein bisschen länger brauchen und diejenigen die überhaupt keinen Plan haben.


Anmelden zum Antworten