• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Viele hassen ihn, manche schwören auf ihn, wir aber möchten unbedingt sehen, welche Bilder Ihr vor Eurem geistigen Auge bzw. vor der Linse Eures iPhone oder iPad sehen könnt, wenn Ihr dieses Wort hört oder lest. Macht mit und beteiligt Euch an unserem Frühjahrsputz ---> Klick

C++ delete *pointer

creative7even

Jerseymac
Registriert
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.
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
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
 
  • Like
Reaktionen: creative7even

creative7even

Jerseymac
Registriert
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...
 
Zuletzt bearbeitet:

pi26

Adams Parmäne
Registriert
17.12.04
Beiträge
1.297
MacApple schrieb:
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

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
 
Zuletzt bearbeitet:

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
pi26 schrieb:
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.
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
 

tjp

Altgelds Küchenapfel
Registriert
07.07.04
Beiträge
4.059
creative7even schrieb:
Hallo an alle C++ Hacker:

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 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;
   }
};
 
  • Like
Reaktionen: creative7even

pi26

Adams Parmäne
Registriert
17.12.04
Beiträge
1.297
MacApple schrieb:
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.

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 :)
 

MacApple

Schöner von Bath
Registriert
05.01.04
Beiträge
3.652
pi26 schrieb:
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.
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
 

Binary

Gast
mfg pi26
__________________
--Powered by Applescript - Sound "Tännkomatu"
set alist to {"10,2,3,10,2", "10,2,3,com2,2", "innovation and roots", "3,10 2 2 com"}
repeat with k from 1 to 3
repeat with i from 1 to count of alist
say item i of alist using "Bubbles"
say item ((count of alist) - i + 1) of alist using "Whisper"
say item i of alist using "Bubbles"
end repeat
end repeat

muha, dass is ma ne geile Signatur ;)

lg