1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

C++ delete *pointer

Dieses Thema im Forum "AppleScript" wurde erstellt von creative7even, 30.10.05.

  1. creative7even

    creative7even Jerseymac

    Dabei seit:
    23.02.05
    Beiträge:
    454
    Hallo an alle C++ Hacker:

    habe Probleme mit der Speicherfreigabe:

    Code:
    headerfile:
    
    #define NULL 0
    typdef struct Node {
      Node *next;  
      int n;
    } Node;
    
    cpp-file:
    
    void deleteNode (Node *node) {
      delete node;
      node = NULL;
      cout << node << endl; // gibt '0' aus
    }
    
    
    void doSomething () {
      ...
      Node *node =  new Node;
      ...
      deleteNode(node);
      cout << node << endl; // Gibt aber eine Hex-Adresse aus?!
    }
    
    
    Das Problem ist jetzt, dass in node jetzt ein Hex-wert steht. Wie kann ich überprüfen dass der pointer auf keinen reservierten Speicherbereich mehr zeigt?

    danke euch schon mal...
    c7.
     
  2. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Die Zeigervariablen "node" in den beiden Funktionen deleteNode(Node*) und doSomething() sind zwei verschiedene Variablen. Wenn Du in deleteNode(Node*) der Variablen "node" dort NULL zuweist, ändert das nichts an der Variablen in doSomething(), denn es gilt: (&node von doSomething()) != (&node von deleteNode(Node*)).

    MacApple
     
    creative7even gefällt das.
  3. creative7even

    creative7even Jerseymac

    Dabei seit:
    23.02.05
    Beiträge:
    454
    danke für die schnelle antwort!
    aber... wie kann ich dann einen call by reference (mit einem pointer) durchführen?
    Sollte doch generell möglich sein?


    EDIT:

    ok.... ich glaube ich habe hier ein 'dangling pointer' Problem. Habe nämlich 2 einfach verkettete Listen die z.T. auf die selben Node-Elemente zeigen. Lösche ich aus Liste1 ein Element auf das in Liste2 auch verwiesen wird, so entsteht ein 'dangling pointer' Problem. Ich dachte, ich könnte Liste2 durchlaufen, und die Verweise auf freigegebenen Speicher löschen. Tja, falsch gedacht.
    danke trotzdem für eure hilfe...
     
    #3 creative7even, 30.10.05
    Zuletzt bearbeitet: 30.10.05
  4. pi26

    pi26 Adams Parmäne

    Dabei seit:
    17.12.04
    Beiträge:
    1.297
    hm, also dann ist C aber völlig unverwandt. Da wird ja doch ein Pointer als Parameter übergeben. Sehe irgendwie nicht wie dann da zwei Variablen da sein sollten. Meiner Meinung nach (analog zu C) sollte es doch einfach heissen

    delete *node;

    PS: ausserdem würde ich mir erwarten, dass C++ ein direktes Delete ermöglicht, z.B.
    delete node;


    mfg pi26
     
    #4 pi26, 30.10.05
    Zuletzt bearbeitet: 30.10.05
  5. quarx

    quarx Hadelner Sommerprinz

    Dabei seit:
    17.04.05
    Beiträge:
    8.541
    Ja, genau so ist es auch in C++.
     
  6. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Richtig, hier wird ein Pointer als Parameter übergeben. Trotzdem bleiben die Variablen "*node" lokale Variablen, auch in C. Nur, was passiert denn hier?

    Beim Aufruf von deleteNode(Node*) wird die Adresse eines Nodes in die lokale Zeigervariable *node kopiert, d.h. es zeigt nun die lokale Zeigervariable *node von doSomething() und die lokale Zeigervariable *node von deleteNode(Node*) auf die gleiche Stelle im Speicher.
    In deleteNode(Node*) wird dann das Node-Objekt zerstört. Nun zeigen die beiden lokalen Zeigervariablen immer noch auf die gleiche Stelle im Speicher, nur dass sich dort kein gültiges Objekt mehr befindet. Nach der anschließenden Zuweisung von NULL an die lokale Zeigervariable *node von deleteNode(Node*), zeigt diese nun auf die Speicherstelle 0, die lokale Zeigervariable *node von doSomething() zeigt aber weiterhin auf die alte Speicherstelle.

    Code:
    cout << &node << endl;   // gibt die Adresse der Variablen *node aus
    cout <<  node << endl;   // gibt die Adresse aus, auf die *node zeigt
    cout << *node << endl;   // gibt den Wert aus, auf den *node zeigt
    MacApple
     
  7. tjp

    tjp Baldwins roter Pepping

    Dabei seit:
    07.07.04
    Beiträge:
    3.250
    Das ist irgend eine Gebräu aus C und C++. Erste Regel: NULL verwendet man in C++ nie, da es mit jeder möglichen Definition von NULL nur mehr Probleme gibt, als sie lösen könnte. Man sollte immer 0 schreiben, auch wenn das C Programmieren schwer fällt.

    Der Header ist reines C und kein C++. Es gibt keinen Grund das so in C++ zu tun. Nachfolgend habe ich auf die Schnelle versucht eine bessere C++ like Lösung zu schreiben. Der Zeiger auf den nächsten Knoten ist private, man soll ihn von außen gar nicht verändern können, da man so nur mehr Unheil anrichten kann.

    Dann kann es auch nicht so leicht zu hängenden Zeiger kommen wir bei Dir. Wichtig ist vorallem der Destruktor, wenn Du irgend ein Node Element löscht werden alle nachfolgenden mitgelöscht. Will man das nicht, muß man eine spezielle Methode schreiben, die das bewerkstelligt. CC und op= sind nicht implementiert, da müßte man sich darauf einigen, ob man DeepCopy haben wollte oder nicht.

    Code:
    Header
    
    class Node {
       Node*   next;
       Node (Node const&);
       Node& operator= (Node const&);
    public:
       int        n;
       Node () : next(0), int (0) {}
       ~Node() {
          if (0 != this->node) {
            delete this->node;
         }
       }
       Node * const getNextNode() const {
          return this->node;
       }
       void createNextNode() {
          if (0 != this->node) return;
          this->node = new Node;
       }
       void deleteNextNode() {
          if (0 == this->node) return;
          delete this->node;
       }
    };
    
     
    creative7even gefällt das.
  8. pi26

    pi26 Adams Parmäne

    Dabei seit:
    17.12.04
    Beiträge:
    1.297
    Gut, ist im Gegensatz zu deiner ersten Erklärung ja auch okay - wobei die erste Erklärung letztlich auch nicht falsch aber eher unnötig war. Der Funktionsparameter von deleteNode ist als solcher logischerweise lokal, wobei er als Pointer andererseits natürlich auf einen nichtlokalen gemeinsamen Inhalt zeigt. Zudem bezeichne ich einen Pointer (speziell als Funktionsparameter) - obwohl natürlich veränderbar - auch nicht als Variable.


    mfg pi26 :)
     
  9. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    Na ja, in meiner ersten Erklärung habe ich eigentlich nichts anderes gesagt und habe nur versucht zu erklären, wieso beim cout in doSomething() ein Hexwert ausgegeben wird.

    MacApple
     
  10. Binary

    Binary Gast

    muha, dass is ma ne geile Signatur ;)

    lg
     

Diese Seite empfehlen