hilfe mit pointern



    void(char* p, int* x)
    

    Da fehlt doch was.

    2. Wenn das dort eingesetzt ist, fehlt immer noch eine Forwardeclaration, oder gleich die ganze Funkton nach oben.



  • int main()
    {
        char* p=0;
        int* x=0;
        init(p,x);
        ...
    }
    
    void(char*& p, int*& x)
    {
        p = new ...;
        x = new ...;
    }
    

    edit: Aber schön ist das definitiv nicht! Guck dir evtl mal std::auto_ptr oder die boost-Zeigerwrapper an, da wird man glücklicher mit.



  • Danke Badestrand das habe ich gesucht aber warum ist das nicht schön? 😕
    ja oben steht noch der prototyp der funktion. den qt habe ich nur schnell hier geschrieben da mein qt schon knappe 800 zeilen hat^^



  • KOR schrieb:

    Danke Badestrand das habe ich gesucht aber warum ist das nicht schön? 😕

    Weil es gefährlich ist und dir sehr schnell Memoryleaks geben kann. (Wer kümmert sich um das aufräumen des mit new reservierten Platzes?)



  • um die zeiger zu verändern müssen sie als zeiger oder referenzen übergeben werden. zum auslesen reicht es, sie per wert (zeigerwerte sind adressen), zu übergeben.

    #include <iostream>
    using namespace std;
    
    //zeiger werden über zeiger übergeben
    void init(char **c, int **i)
    {
        //reserviert speicheradressen und weist sie den zeigern zu
        *c = new char; //der operator * derferenziert
        *i = new int;
    
        //weist den reservierten speicheradressen (nicht den zeigern!) werte zu
        **c = 'a'; //hier wird zwei mal derferenziert, da nicht der per zeiger übergebene zeiger, sondern der inhalt der adresse gemeint ist, die er als wert hat.
        **i = 4711;
    }
    
    //zeiger werden über referenzen übergeben
    void finish(char *&c, int *&i)
    {
        //gibt die speicheradressen frei
        delete c;//durch die übergabe per referenz wird automatisch dereferenziert, so dass der operator * hier nicht nötig ist.
        delete i;
    
        //weist den zeigern 0 zu, um ihre ungültigkeit überprüfbar zu machen
        c = 0;
        i = 0;
    }
    
    //zeiger werden übergeben, indem ihr wert,
    //also die gespeicherte adresse,
    //kopiert wird
    void test(char *c, int *i)
    {
        if (c != 0)
        	cout << "c zeigt auf den Wert " << *c << "\n";
        else
            cout << "c darf nicht dereferenziert werden, da es die Spezialadresse 0 als Wert hat!\n";
    
        if (i != 0)
        	cout << "i zeigt auf den Wert " << *i;
        else
            cout << "i darf nicht dereferenziert werden, da es die Spezialadresse 0 als Wert hat!";
    
        cout << endl;
    }
    
    int main()
    {
        char *p=0;
        int *x=0;
    
        test(p, x);
        init(&p, &x);
        test(p, x);
        finish(p, x);
        test(p, x);
    }
    


  • sry ich bin in sowas ein ziemlicher noob aber wird das nicht spätestens mit dem ende des programmes wieder freigegeben? (falls ich vergesse nach dem benutzen sie mit delete freizugeben)



  • wenn dein betriebssystem lieb ist, dann ja 😉



  • danke zeig das ist ja eine super ausführliche antwort. Das mit den pointer-to-pointer ist jetzt nicht so memoryleak gefärdet??



  • doch. was mit new angefordert wird, sollte auch mit delete wieder freigegeben werden. das kann in dem beispiel jederzeit mit dem aufruf der funktion finish gemacht werden.

    in der tat ist es aber so, dass heutzutage die meisten betriebssysteme den speicher nach dem ende des programms wieder frei geben. des problem ist, wenn programme lange laufen, wie zum beispiel server, und immer wieder speicher reserviert wird, für den keine freigabe erfolgt, wenn er nicht mehr benötigt wird.



  • Grundsätzlich gilt, dass du mit new angeforderten Speicher mit delete (bzw. new[], delete[] bei Feldern) wieder freigeben sollst, gemäß der Prämisse "Don't expect anything" (in dem Fall der Freigabe des Speichers durch das OS).

    Die init-Funktion lässt auch Schlüsse zu, dass du es mal mit Klassen probieren solltest. Hier kannst du angeforderten Speicher durch den Desktruktor "automatisch" freigeben lassen. In vielen Fällen kommt man aber drum herum, dynamischen Speicher mittels new anfordern zu müssen. Die STL bietet viele nützliche Hilfsmittel (std::vector<T>, std::string, std::list<T>, um einige zu nennen), welche dir die Arbeit mit dyamisch angeforderten Speicher abnehmen.

    Wenn du bestehende Variablen einfach ändern willst, dann ist die Übergabe per Referenz die sinnvollste (m.E.).

    Die 800 Zeilen Quelltext lassen sich bestimmt um einiges reduzieren und übersichtlicher gestalten, wenn man die oben genannten Sprachmittel verwendet. 😉

    Grüße... Heiko


Anmelden zum Antworten