Zugriffsverletzung beim rausspringen aus Methode



  • Doch, im Debugger sieht das Objekt ganz in Ordnung aus. Der Wert ist auch gesetzt...
    Was mir noch aufgefallen ist, daß ich noch eine Klassenvariable "type" habe in Klassen A und C (in A auf 1 gesetzt und in C auf 2) und dazu eine virtuelle Methode "getType()". Wenn das Objekt in dem Array ein Pointer auf C ist, müßte bei getType() also 2 geliefert werden. Das passiert auch. Aber wenn ich mir dasselbe Objekt im Debugger ansehe (mit "untersuchen" im Borland Builder), steht bei "type" 1 drin. Das ist allerdings auch schon bei Objekten so, bei denen es zu keinem Fehler kommt.
    Also, das kommt mir merkwürdig vor, ich kann aber trotzdem keinen Zusammenhang zu der Fehlermeldung erkennen.

    Also, wenn jemand noch eine Idee hat, wär echt super!



  • Habs nochmal alles zusammen neu aufgeschrieben:

    class A {
        protected:
        double  itsVar;
        static int type;
    
        public:
        double getVar();
        virtual int getType();
    }
    
    class B : public A{
    }
    
    class C: public B{
        protected:
        static int type;
    
        public:
        virtual int getType();
    }
    
    int A::type=1;
    int C::type=2;
    
    int A::getType() {
           return type;
    }
    
    int C::getType() {
           return type;
    }
    
    double A::getVar() {
         return itsVar;
    }
    

    Das Array dann schließlich, von dem aus aufgerufen wird:

    A* Arr[xsize][ysize][3];
    
    if ( (Arr[x][y][0]!=0) && (Arr[x][y][0]->getType()==2) )
    {             
        Arr[x][y][0]->getVar();
    ...
    }
    


  • Mir fallen bei diesem CodeAusschnitt ungefähr 7 potenzielle Fehlerquellen auf.


  • Mod

    Wird Arr überhaupt initialisiert? Was bedeutet "untersuchen" im Debugger beim Borland Builder - interessiert der sich für den dynamischen Typ des Objektes?
    Nebenbei: Probleme, die der Debugger etwa bei der Überwachung von Variablen hat, sollten nur mit Vorsicht als Fehler qualifiziert werden. Es ist schließlich normal, dass zum Beipiel das Objekt hinter einem Nullzeiger oder einem Zeiger, der nicht initialisiert wurde, nicht überwacht werden kann - ohne dass diese Tatsache allein einen Programmfehler darstellt (ein Programmfehler liegt erst vor, wenn das Programm selbst den Objektzustand feststellen will).



  • @templäd:
    Welche denn?

    @camper:
    Ja, Arr wird initialisiert, aber nicht in jedes Feld wird was reingeschrieben, weswegen ich ja bzgl. Gleichheit auf 0 teste.
    Tja, das mit dem dynamischen Typ ist beim Borland Builder so ein bißchen "von hinten durch die Brust ins Auge", was den Typ selbst angeht. Ich dachte aber, daß da bei den Variablen schon die richtigen Werte drinstehen. Hm, von irgendwas muß ich aber doch ausgehen, dafür ist ein Debugger doch da?! Na ja, so oder so IST da ja ein Fehler...


  • Mod

    susie schrieb:

    Ja, Arr wird initialisiert, aber nicht in jedes Feld wird was reingeschrieben

    Das ist irgendwie ein Widerspruch, oder nicht? Auch 0 ist etwas und steht da nicht (im Allgemeinen) von vornherein ohne das Zutun des Programmierers.

    susie schrieb:

    Tja, das mit dem dynamischen Typ ist beim Borland Builder so ein bißchen "von hinten durch die Brust ins Auge", was den Typ selbst angeht.

    Sehr metaphorisch. Sagt mir überhaupt nichts.
    Die Frage anders formuliert: Angenommen (du kannst das ja zu Testzwecken hinzufügen), Klasse C hat eine zusätzliche Membervariable, die nicht mit einer gleichnamigen Variable der Klasse A kollidiert. Erlaubt der Debugger dir dann, diese Membervariable in diesem Kontext (also über einen Zeiger des Typs A*) zu inspizieren?



  • Ok, ist die Frage, wie man "initialisiert" definiert. Aber wenn ich jedesmal auf 0 teste, sollte das doch egal sein?!

    Sehr metaphorisch. Sagt mir überhaupt nichts.

    Da hast Du recht 😉
    Erstmal das hier als Erklärung:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-214397-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html
    Zu den Variablen schreibe ich später noch was...



  • susie schrieb:

    Aber wenn ich jedesmal auf 0 teste, sollte das doch egal sein?!

    camper schrieb:

    Auch 0 ist etwas und steht da nicht (im Allgemeinen) von vornherein [drin]

    ➡ Wenn Du vorher 0 reinschreibst. Wenn nicht, bringt Dein Vergleich auf 0 garnichts.


  • Mod

    susie schrieb:

    Ok, ist die Frage, wie man "initialisiert" definiert.

    Initialisierung bedeutet, ein Objekt in einen definierten Anfangszustand zu versetzen. Die Initialisierung eines Arrays ist abgeschlossen, wenn alle seine Elemente initialisiert wurden. Ein Objekt, dass nicht initialisiert wurde, hat einen unbestimmten Zustand/Wert. Die Benutzung eines unbestimmten Wertes ist undefiniert. Insbesondere ist ein nicht initialiserter Zeiger kein Null-Zeiger.



  • Hallo,

    da hat sich mein Posting gestern abend mit camper überschnitten.

    Ja, also mit 0 initialisiere ich es (oder weise eben einen Pointer auf ein Objekt zu), s. unten.

    So, und zur Variablendarstellung im Debugger:
    Instanzvariablen der Klasse C (die nicht in A vorkommen) kann ich mir ansehen, wenn ich in einer Methode von C bin. Ansonsten nicht (das dürfte wohl auch das Problem gestern bei der Klassenvariable type gewesen sein). Von daher müßte die Fehlermeldung meiner Meinung nach dann wohl doch mit was anderem zu tun haben.

    Hier also nochmal explizit der Code zur Initialisierung.
    Klasse C1 erbt auch von B, Klassen D und D1 erben von einer "Schwesterklasse" von B, nur der Vollständigkeit halber.

    for (int x=0; x<xsize; x++) {
             for (int y=0; y<ysize; y++) {
                 for (int z=0; z<2; z++) {
    
                     zuf=rand()/(double) RAND_MAX;
                     if (zuf<0.3) {
                        Arr[x][y][z]=new C(0.4,x,y,z);
                     } else if (zuf<0.3+0.1) {
                        Arr[x][y][z]=new C1(0.4,x,y,z);
                     } else if (zuf<0.3+0.1+0.2) {
                        Arr[x][y][z]=new D(0.4,x,y,z);
                     } else if (zuf<0.3+0.1+0.2+0.2) {
                        Arr[x][y][z]=new D1(0.4,x,y,z);
                     } else {
                        Arr[x][y][z]=0; 
                     }
                 }
                 Arr[x][y][2]=0;
             }
         }
    
         for (int x=0; x<xsize; x++) {
             for (int y=0; y<ysize; y++) {
                 if ((Arr[x][y][0]!=0) && (Arr[x][y][1]!=0) && (typeid(*(Arr[x][y][0]))==typeid(*(Arr[x][y][1])))) {
                    Arr[x][y][0]->setVar(0.8);
                    Arr[x][y][1]=0;
                 }
             }
         }
    


  • Hallo nochmal,

    ich hoffe, es war nicht zu verwirrend, daß ich das mit dem Debugger geschrieben habe, war mir halt nur aufgefallen. Sonst fällt mir halt nur leider gar nichts auf und ich hab keine Idee, was es sein könnte. (an den Zugriffsrechten kanns auch nicht wirklich liegen, oder? Habs außerdem die Instanzvariablen mit public statt protected ausprobiert, das hat auch nichts geändert)
    Also, würd mich echt freuen, wenn jemand eine Idee hat.

    Vielen Dank!



  • Ich habs gefunden!!!! Yippiee!
    Problem war, daß ich den hier dargestellten Aufruf

    Arr[x][y][0]->getVar()
    

    in eine weitere Funktion gepackt habe, die den Wert wohl in ein Array schreibt. Dieses Array war nicht richtig dimensioniert. Und diese weitere Funktion hab ich deshalb hier nicht erwähnt, weil es ein sehr spezielles Plug-In für C++ ist, daß heir wohl niemand kennt. Grmpf, und ich selbst hab den Wald vor lauter Bäumen nicht gesehen bzw. hab den Fehler eher auf meine mangelnden C++ -Kenntnisse geschoben. Na ja, nu läuft's... 🙂


Anmelden zum Antworten