Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Funktionsaufruf verändert Speicherreferenz

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
23.09.2006, 13:42 Uhr
fp



Hi,
ich habe ein merkwürdiges Problem, konnte auch nichts passendes dazu finden:

Ich habe eine Implementierung eines simples Stacks, dessen Elemente lediglich Integerwerte speichern sollen. Was daran nun nicht funktioniert ist mir einfach nur noch ein Rätsel.
Es wird nur das oberste Element vom Stack richtig gespeichert. Das Testprogramm soll einfach erst Werte drauflegen und jedesmal schauen, was nun oben auf dem Stapel liegt, danach die Elemente wieder löschen, und nach jedem Löschen wieder prüfen was oben liegt.

Jedes Element hat einen Zeiger auf ein Stackelement, nämlich das darunter liegende. Bei der Initialisierung des ersten Elements ist deshalb dieser Zeiger korrekt auf NULL gesetzt, weil es ja das einzige Element ist und nichts darunter liegt. Sobald allerdings die pop() Funktion aufgerufen wird, ist dieser Zeiger verändert und zeigt irgendetwas anderes, somit sind alle Daten, wenn man mehrere Elemente speichert, eben nicht mehr zugreifbar.

Woran könnte das liegen ? Beim Test wird zuerst nur ein Element dem leeren Stack hinzugefügt und danach sofort wieder gelöscht, sobald pop() zum Löschen aufgerufen wird, ist der next-Zeiger aber nicht mehr NULL, obwohl er das sein sollte. Beim Aufruf von top(), nur zum schauen was auf dem Stack liegt, passiert jedenfalls nichts.
Ich habe mir die Speicherreferenzen von dem obersten Objekt, und auf was sein next-Zeiger zeigt, bei jedem Funktionsaufruf ausgeben lassen und der next-Zeiger des obersten Elements geht erst beim Aufruf von pop() kaputt, ohne dass die Funktion irgendwas anstellt.
(Diese Testausgaben hab ich bei dem Code unten aber weggelassen).


C++:
#include <iostream>
using namespace std;

class StackElem {
private:
    int value;
    StackElem* next;
public:
    StackElem(int a) { value = a; next = NULL; }
    StackElem() {}
    StackElem* get_next() {
        return next;
    }
    void set_next(StackElem* n) {
        next = n;
    }
    int get_value() {
        return value;
    }
    void set_value(int v) {
        value = v;
    }
};

class Stack {
private:
    StackElem* head;
public:
    
    Stack() { head = NULL; }
    void top() {
        if(head == NULL)
            cout<<"\nStack is empty";
        else
            cout<<"\ntop element: "<<(*head).get_value();
    }
    void push(int val) {
        StackElem new_elem(val);
        if(head == NULL)
            head = &new_elem;
        else {
            new_elem.set_next(head);
            head = &new_elem;
        }
    }
    void pop() {
        if(head == NULL)
            cout<<"\nStack is empty, nothing to delete";
        else {
            cout<<"\ndeleting top element with value: "<<(*head).get_value();
            head = (*head).get_next();
        }
    }
};

// stack test

int main() {
    
    Stack my_stack;
    int opt=100;
    int ins=0;

    my_stack.push(2);    my_stack.top();
    my_stack.pop();        my_stack.top();
    my_stack.push(3);    my_stack.top();
    my_stack.push(4);    my_stack.top();
    my_stack.push(5);    my_stack.top();
    my_stack.pop();        my_stack.top();
    my_stack.pop();        my_stack.top();
    my_stack.pop();        my_stack.top();
}



Ich verwende den gcc 3.4.6
Falls mir das jmd erklären könnte wäre das super :/

mfg, fp

Dieser Post wurde am 23.09.2006 um 13:52 Uhr von fp editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
23.09.2006, 13:56 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi du verwendest immer die adresse von lokalen variablen in der push-methode -> nach verlassen ist der pointer auf das element ungültig. du musst die elemente schon neu mit new und beim destruktor/pop dann mit delete entfernen.
--
class God : public ChuckNorris { };

Dieser Post wurde am 23.09.2006 um 14:24 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
23.09.2006, 14:11 Uhr
~fp
Gast


:O
klappt.

Danke für die schnelle Antwort. Ist ja auch logisch, bin aber nicht drauf gekommen. Ist wohl so ne Art Tunnelblick in solchen Momenten .

mfg, fp
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: