anfaenger-Frage zu pointern



  • Hmmm,

    also meinen default-Konstructor habe ich wie folgt definiert:

    //Default Konstruktor
    
    structclass()
    	 : knoten1(0), knoten2(0)
    

    wenn erforderlich, fülle ich das Feld, dass den Pointer auf das nachfolgende Feld enthalten soll mit

    (*aktuellzeiger).knoten1=&nachfahre;
    

    Dass heißt doch, dass nicht gefüllte Felder den Wert 0 durch den Konstruktor enthalten müssen und nicht uninitialisiert sein können? Oder mache ich es mir zu einfach? Benutzt new nicht den default-Konstruktor? Ich fülle die pointer auch nur einmal und verändere sie nicht mehr. Und ich fülle sie nur dann, wenn ich ein neues Objekt erzeuge und dieses an meine Struktur anhängen möchte.

    Der Befehl vor dem erneuten rekursiven Funktionsaufruf beim Ausgeben des Baumes

    std::cout <<"Linkes Kind: "<< (*knoten_zeiger).knoten1 <<std::endl;
    

    führt zu folgender Ausgabe:

    Linkes Kind: 0xbfffec60

    Und der nachfolgende rekursive Funktionsaufruf mit diesem Pointer dann zu einem Speicherzugriffsfehler.
    Heißt das dann, das die Adresse auf etwas zeigt, dass nicht mit Speicherplatz für das Objekt auf den der Pointer zeigt, übereinstimmt? Wenn die Adresse an das Feld übergeben wurde in der baum erzeugenden Funktion, dann muß es doch mal da gewesen sein. Wieso ist es dann jetzt verschwunden???
    Ich stehe gerade ganz schön auf dem Schlauch... 😢
    Ach noch was... Wenn in (*knoten_zeiger).knoten1 eine Adresse steht, ist es dann wirklich das richtige, was man als Pointer an die nächste Funktion übergeben muß?

    Aber schon mal vielen Dank für Eure Hilfe.



  • ox........ sind adressen, die nicht ok sind bzw. darauf schließen lassen, dass nicht initialisiert wurde?
    Dann klappt vielleciht was beim Konstructor-Aufruf nicht. Muß ich ihn explizit selbst aufrufen?
    Ausserdem bin ich mir speziell beim ersten Feld sicher, dass da eine Adresse übergeben wird. Vielleicht stimmt da was nicht. Ich sehe noch mal drüber... 😢



  • Der Ausdruck (*aktuellzeiger).knoten1 wird im allgem. aktuellzeiger->knoten1 geschrieben. So wird das ganze schon mal etwas übersichtlicher und Fehler lassen sich leichter erkennen.

    Du schreibst:
    "Dass heißt doch, dass nicht gefüllte Felder den Wert 0 durch den Konstruktor enthalten müssen und nicht uninitialisiert sein können? Oder mache ich es mir zu einfach? Benutzt new nicht den default-Konstruktor?"

    Kannst du mal kurz erklären, was du unter deinem default-Konstruktor verstehst ?



  • Ich glaube, ich mache im Folgenden was falsch:

    structclass* nachfahrezeiger = new structclass;
    

    legt ein Objekt an und lässt nachfahrezeiger darauf zeigen. Richtig?

    structclass nachfahre;
    

    legt ein Objekt nachfahre an, dass aber nur lokal vorhanden ist und nach Verlassen der Funktion wieder verschwindet.

    (*aktuellzeiger).knoten1=&nachfahre;
    nachfahrezeiger = &nachfahre;
    baum_erzeugen(nachfahrezeiger, datei);
    

    das Zeigerfeld (knoten1) des Objekts aus der vorangegangenen Funktion (auf das aktuellzeiger zeigt) wird also mit dem Pointer auf ein Objekt gefüllt, dass nach dem Funktionsaufruf wieder verschwindet! Also der Fehler!

    Lösung müßte also sein, das Objekt ohne Namen, auf das Nachfahrezeiger zeigt zu füllen und einfach nachfahrezeiger an die nächste Funktion zu übergeben. Oder?
    Also etwa so:

    structclass* nachfahrezeiger = new structclass;
    (*aktuellzeiger).knoten1=nachfahrezeiger;
    baum_erzeugen(nachfahrezeiger, datei);
    

    Bei Zeile zwei

    (*aktuellzeiger).knoten1=nachfahrezeiger;
    

    bin ich mir nicht so sicher, was man eigentlich übergeben muß. Kann man da einfach die Poinzer-Variable reinsetzen?

    Könnte es generell so richtig sein?Ich glaube, ich mache im Folgenden was falsch:

    structclass* nachfahrezeiger = new structclass;
    

    legt ein Objekt an und lässt nachfahrezeiger darauf zeigen. Richtig?

    structclass nachfahre;
    

    legt ein Objekt nachfahre an, dass aber nur lokal vorhanden ist und nach Verlassen der Funktion wieder verschwindet.

    (*aktuellzeiger).knoten1=&nachfahre;
    nachfahrezeiger = &nachfahre;
    baum_erzeugen(nachfahrezeiger, datei);
    

    das Zeigerfeld (knoten1) des Objekts aus der vorangegangenen Funktion (auf das aktuellzeiger zeigt) wird also mit dem Pointer auf ein Objekt gefüllt, dass nach dem Funktionsaufruf wieder verschwindet! Also der Fehler!

    Lösung müßte also sein, das Objekt ohne Namen, auf das Nachfahrezeiger zeigt zu füllen und einfach nachfahrezeiger an die nächste Funktion zu übergeben. Oder?
    Also etwa so:

    structclass* nachfahrezeiger = new structclass;
    (*aktuellzeiger).knoten1=nachfahrezeiger;
    baum_erzeugen(nachfahrezeiger, datei);
    

    Bei Zeile zwei

    (*aktuellzeiger).knoten1=nachfahrezeiger;
    

    bin ich mir nicht so sicher, was man eigentlich übergeben muß. Kann man da einfach die Pointer-Variable reinsetzen?

    Könnte es so richtig sein?



  • Ich habe gelesen, wenn man Objekte mit
    structclass objektname; erzeugt, wird der default-Konstruktor verwendet, dem man bei der Klassendefinition Initialisierungswerte übergeben hat.
    Ansonsten kann man dem Konstruktor auch Werte übergeben mit
    structclass objektname(wert1, wert2, etc.);
    natürlich nur so, wie der Konstruktor definiert wurde.
    Und ohne Klammer und Werte ist eben Aufruf des Default-Konstruktors.



  • ... und danke für den Tipp mit der vereinfacxhten Schreibweise. Sieht wirklich übersichtlicher aus.



  • Du musst aufpassen ob du von der Adresse sprichst die der Zeiger selbst hat, oder von der Adresse, auf die er verweist.

    Bitte verwende den "->"-Operator. Dann kommst'e auch nicht mehr durcheinander !

    Andere Baustelle:
    Der Default-Konstruktor reseviert den Speicher, er wird aber nicht explizit initialisiert. Der Inhalt ist also zufällig, wenn du dich nicht drum kümmerst.



  • aktuellzeiger->knoten1=nachfahrezeiger;
    ..dem "Inhalt" von aktuellzeiger->koten1 die Adresse von nachfahrerzeiger zuweisen

    aktuellzeiger.knoten1=nachfahrezeiger;
    die Adresse auf die aktuellzeiger->koten1 zeigt, durch die Adresse von nachfahrerzeiger ersetzen





  • Aber ich definiere den Default-Konstruktor in der Klassenbeschreibung doch explizit mit default werden:

    //Default Konstruktor

    structclass()
    : knoten1(0), knoten2(0)

    Bedeutet dass nicht, dass beim Erzeugen mit new die Variablen knoten1 und knoten2 mit 0 belegt werden?
    Dann muß ich noch mal was dazu lesen.

    Das andere funktioniert jetzt übrigens! 🙂

    Danke sehr für Eure Hilfe!
    Und danke für den Link. Werde ich mir durchlesen.



  • Hallo tina_anfaenger2,

    hab gerade noch mal reingeschaut.

    Warum arbeitest du nicht mit einer Struktur (z.B. struct Knotenelement oder Listenelement) ? Darin definierst'e lediglich die Variablen für deine Daten und einen Zeiger next auf den nachfolgenden Knoten und einen Zeiger last auf das Knotenelement davor.

    Dann definierste ganz global einen Zeiger auf den Listenanfang und einen Hilfszeiger, um dich in der Liste bewegen zu können.

    Danach brauchste noch eine Funktion zum Initialisieren des ersten, mit new() zu erzeugenden Knotenobjektes (Listenanfang = new(Knotenelement), Listenanfang->next = NULL, Listenanfang->last=NULL, DeineDaten=irgenswas).

    In den Funktionen zum Einfügen (next-Zeiger des akt. Objektes auf das neu erzeugte Knotenelement setzen usw.) oder Löschen (next-Zeiger des akt. Objektes auf NULL setzen usw.) musst'e dann lediglich die Adresse der neu erzeugten Objekte in die Zeiger der aktuellen, schon existenten Objekte (i.d.R. Vorgänger oder Nachfolger) eintragen.

    Und wenn das alles klappt. Kannst'e mal probieren aus der Struktur eine Klasse zu machen, indem du die Funktionen darin integrierst.

    Viel Spaß.


Anmelden zum Antworten