Doppelpointer - Wofür?
-
Hallo!
Ich habe mich eben gefragt, wo Doppelpointer (**) in der Anwendung Verwendung finden.
Mir jedenfalls ist kein sinnvolles praktisches Beispiel eingefallen.
-
Naja, die DirectX-Funktionen machen davon intensiven Gebrauch! Du deklarierst einen Zeiger auf ein COM-Interface, und übergibst einer Funktion einen Zeiger auf deinen Zeiger. Dein Zeiger zeigt danach hoffentlich auf ein erfolgreich instanziertes Objekt.
Sehr oft braucht man die aber wohl wirklich nicht.
-
Ich hab Doppelpointer in C gerne für mathematische Matrizen benutzt. Also wenn ich dynamisch mit calloc() Speicher alloziert habe. Hier mal ein kleines Beispiel aus nem Programm, das ich für die Uni schreiben musste.
double** creat_matrix(int i) { int j; double **matrix; //Erstelt 1-dim. Feld (Zeilen) von double-Zeigern matrix = (double**) calloc(i, sizeof(double*)); //Überprüft, ob calloc()-Aufruf konrekt ablief if(matrix == NULL) { printf("Speicher konnte nicht reserviert werden\n"); //Sollte es zu Problemen gekommen sein, Speicher leeren free(matrix); //Programm beenden exit(1); } for(j = 0;j < i; j++) { //erstellt zur i-ten Zeile ein eindimensionales Feld der Länge i (Spalten) matrix[j] = (double*) calloc(i, sizeof(double)); //Ist die Speicherreservierung nicht erfolgreich, dann wird jedes zuvor erfolgreich reservierte Feld //wieder freigegeben if(matrix[j] == NULL) { int x; for(x = 0; x < j; x++) { free(matrix[x]); } //gibt zum Schluss den "Zeilen-Zeiger" frei free(matrix); printf("Speicher konnte nicht reserviert werden\n"); exit(1); } } return matrix; }
-
Manchmal willst du, dass die Adresse worauf der Zeiger zeigt, geändert wird. Wenn das in der selben Funktion geschieht, wo der Zeiger deklariert wurde, dann ist es wie eine normale Variablenzuweiseung
void foo(void) { char *p = NULL; p = "Hallo"; }
Aber wenn du
p
an eine Funktion übergibst, und diese die Adresse ändern sollst, dann wäre die veränderung nur innerhalb der aufgerufene Funktion sichtbarvoid bar(char *txt) { txt = "nur hier sichtbar"; /* txt ist nur eine Kopie von p, aber nicht p selber, d.h. txt zeigt worauf p zeigt, aber nicht auf p */ } void foo(void) { char *p = NULL; p = "Hallo"; /* p zeigt auf "Hallo" */ bar(p); /* p zeigt weiterhin auf "Hallo" */ }
ähnlich wenn ich den Inhalt einer int-Variable in einer anderen Funktion verändern will. Abhilfe dazu? Man übergibt den Zeiger der int-Variable und über den kann die aufgerufene Funktion die ursprüngliche Variable verändern. Mit (einfachen, sprich nur mit einem Stern deklarierten) Zeigern ist es genau dasselbe, weil Zeiger ebenfalls Variablen sind:
void bar(char **txt) { /* txt ist nur eine Kopie des Zeigers auf p, also zeigt auf p mit *txt können wir auf p zugreifen und es verändern, d.h. verändern worauf p zeigt. mit **txt können wir darauf zugreifen, worauf p zeigt */ *txt = "Welt"; } void foo(void) { char *p = NULL; p = "Hallo"; /* p zeigt auf "Hallo" */ bar(&p); /* p zeigt nun auf "Welt" */ }
-
Bei Bäumen und ähnlichen Datenstrukturen machen sie oft die Implementierung leichter und eleganter. Beispiel:
struct Node{ Node**parent_ptr; Node*left, right; }; struct Tree{ Node*root; };
parent_ptr kann auf ein Node::left oder Node::right aber auch ein Tree::root zeigen. Dadurch braucht die Wurzel in den allermeisten Funktionen Fällen nicht sonder behandelt zu werden und man braucht auch nicht zwischen linkem und rechtem Kind zu unterscheiden. Um den Vaterzeiger zu verändern reicht in allen drei Fällen ein *(node->parent_ptr) = new_node.