Referenz auf Pointer. Wozu? - fkt(int*& t)



  • Hallo zusammen!

    Kann mir mal jemand folgenden Aufruf an einem Beispiel klar machen?

    fkt(int*& t)

    Wozu braucht man einen solchen Aufruf? Ginge nicht auch einfach fkt(int* t)?

    Gruß heine



  • Das gibt es erstens nur in C++ und zweitens kannst du mit dieser Konstruktion auch das Ziel des übergebenen Pointers ändern und nicht nur die Daten, auf die er zeigt.



  • Ähem, wir sind hier im ANSI C Forum, da gibt's keine Referenzen, die findest du n Stockwerk tiefer im C++ Board.

    Analog zu einer Referenz auf einen Pointer kann man in C aber von einem Pointer auf einen Pointer ausgehen. Dies wird nötig, wenn man z.B. Matrizen durch die Gegend schiebt, oder den Pointer selber manipulieren will. Bei einem "einfachen Pointer" kann ich den Pointer selbst ja nicht manipulieren, da er kopiert wird.

    edit: way too slow...

    MfG

    GPC



  • Vermutlich geht es um C++, weil C keine Referenzen kennt.

    Folgendes:

    /* Header-Kram */
    
    void f(int *x) { x = 0; }
    void g(int *& x) { x = 0; }
    
    int main() {
        int x, *y = &x, *z = &x;
    
        f(y);
        if (y)  { puts("y !=  0");}
    
        g(z);
        if (z) { puts("z != 0"); }
    }
    

    Also: einmal kannst Du den Zielort verändern (bei der Referenz-Variante, also g), beim anderen mal geht es nicht.



  • bei gamecoderz in freier wildbahn gesichtet!

    //sorry, kein C
    template<typename T>
    void safe_delete(T*& t){
       delete t;
       t=NULL;
    }
    


  • Dieser Thread wurde von Moderator/in c.rackwitz aus dem Forum ANSI C in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • volkard schrieb:

    bei gamecoderz in freier wildbahn gesichtet!

    //sorry, kein C
    template<typename T>
    void safe_delete(T*& t){
       delete t;
       t=NULL;
    }
    

    Ist das nun gut, oder nicht?



  • Eigentlich ziemlich unsinnig. Man benutzt schließlich eher selten temporäre Objekte, deren Zeiger noch anderweitig verwendet werden könnte. Entweder geht er am Ende des Scopes oder im Destruktor über den Jordan, in beiden Fällen ist es unwichtig, ob er 0 ist.
    Für die wenigen anderen Fälle (mir fiele jetzt kein konkreter ein) kann man das auch manuell schreiben.



  • Könnte man für Container und for_each benutzen. Allerdings würde ich das dann etwas eleganter schreiben. Und da Destruktoren niemals werfen sollten, schon irgendwo etwas überflüssig. Es sei denn, man löscht Pointer-Container nur teilweise etc. Oder bitte irgendeinen anderen konstruierten Grund einsetzen 🤡



  • 7H3 N4C3R schrieb:

    Oder bitte irgendeinen anderen konstruierten Grund einsetzen 🤡

    Anders gesagt: Irgendeine andere schlechte Designentscheidung vorschieben. 😛
    Beliebt ist auch noch die vorherige Abfrage, ob der Pointer nicht vielleicht NULL ist. Ist ja auch ein großes Geheimnis, daß delete NULL; völlig legal ist.



  • Hallo heine789,

    ich möchte Dir auch nochmal ein Beispiel auf Deine Frage
    Kann mir mal jemand folgenden Aufruf an einem Beispiel klar machen?

    fkt(int*& t)
    

    In dem unterem Beispiel wird es hoffentlich klarer. Die dort verwendete Funktion void foo(char &_npTest1, char* &_npTest2)* hat als Parameter Zeiger die als Referenzen übergeben werden. Damit ist es der Funktion erst möglich neu angelegte Adressen an die aufrufende Instanz (hier: main()) weiterzugeben.
    Werden die Und-Zeichen '&' weggelassen, so gibt foo(..) die Adressen nicht weiter. Das hat zu Folge, das die aufrufende Instanz keine neuen Adressen bekommt. Das Programm stürzt beim Zugriff auf npTest1 und npTest2 ab, weil diese keinen neuen Speicher allokieren (Kein new!).

    Denke daran, dass das Und-Zeichen in C++ mindestens zwei Bedeutungen hat: 1. Referenz-Operator und 2. Adress-Operator.

    Übrigens muss ich Dir danken, dass Du Deine Frage gepostest hast. Ich habe damit ein Problem von mir lösen können, was mich vor einem halben Jahr und jetzt auch wieder aktuell beschäftigt hat. 😉

    Gruss

    Thomas

    /* Header-Kram*/
    
    char* getAdress(int nValue) //Legt neuen char-Pointer an und füllt diese Adresse mit einem Wert.
    {
    	char* _newChar = new char;	//Ja, ich weiss. Nach der Speicherallokierung muss ein delete kommen. 
    															//Ich habe delete aus Gründen der Übersichtlichkeit weggelassen.
    
    	(*_newChar) = nValue;
    
    	return _newChar;
    }
    
    // void foo(char * _npTest1, char * _npTest2) // FEHLER ! Die in der Funktion foo angelegten Zeiger geben nicht die Adresse weiter.
    
    void foo(char* &_npTest1, char* &_npTest2) // Das klappt! Hier dient das Und-Zeichen '&' als Referenzoperator und Nicht als Adressoperator !
    											// Dadurch geben die intern anglegten Zeiger ihre Adresse weiter.
    {
    	_npTest1 = getAdress(70); //Zeige auf einen gültigen Speicherbereich !!!
    
    	_npTest2 = getAdress(80); //Zeige auf einen gültigen Speicherbereich !!!
    }
    
    void foo2(char* _npTest1, char* _npTest2)
    {
    	(*_npTest1) = 71;
    
    	(*_npTest2) = 81;
    }
    
    int main()
    {
    	char* npTest1;
    
    	char* npTest2;
    
    	foo(npTest1, npTest2); //Den Zeigern npTest1 und npTest2 werden neue Adressen und ihre dazugehörigen Werte übergeben.
    
    	cout << "npTest1 = " << *npTest1 << " npTest2 = " << *npTest2 << "\n";
    
    	foo2(npTest1, npTest2); //Die Zeiger npTest1 und npTest2 übergeben ihre Adressen, welche von foo2() gefüllt werden.
    
    	cout << "npTest1 = " << *npTest1 << " npTest2 = " << *npTest2 << "\n";
    
    	char nTest1, nTest2;
    
    	foo2(&nTest1, &nTest2);  //Hier dient das Und-Zeichen '&' als Adressoperator
    
    	cout << "nTest1 = " << nTest1 << " nTest2 = " << nTest2 << "\n";
    
    	cin.get();
    
    	return 0;
    }
    


  • Johnny20056 schrieb:

    Denke daran, dass das Und-Zeichen in C++ mindestens zwei Bedeutungen hat: 1. Referenz-Operator und 2. Adress-Operator.

    3. binäres UND 😉


Anmelden zum Antworten