pointer als referenzparameter einer funktion in der speicher allokiert wird



  • hallöchen... hab da n kleines denkproblem

    zwar hatte ich das glaub ich schon mal gelöst aber irgendwie ists mir wieder entfallen... 😉

    also hier mein problem:

    ich hab n pointer der als parameter an eine funktion übergeben wird.
    in dieser funktion wird dem pointer speicher zugewiesen und dem pointer (ein char...) zeugs zugewiesen...
    nun soll die funktion beendet werden aber der mit new erstellte speicher bleibt ja erhalten, was ich auch will um damit außerhalb der funktion weiterarbeiten zu können..
    nur hat der pointer den ich übergeben habe nach dem verlassen der funktion den inhalt des speichers nicht mehr...

    mir war so als hätte ich damals irgendwie mit pointer auf pointer auf char oder sowas gemacht, weil irgendwie sonst die alte addresse beim allokieren überschrieben wurde?

    ...

    void func(char **p);

    void main()
    {

    char **p_char = new char; // allokation hier schon weil sonst warnung beim
    //übergeben eines undef. pointers;
    func(p_char);
    cout << **p_char;
    delete[] p_char;
    }

    void func(char **p)
    {
    delete[] **p; // weg mit tmp. erstellten speicher

    (char*)*p = new char[100];

    strcpy(**p, "test");

    return;
    }

    // und nein ich wills nicht über den rückgabedings der funktion haben sondern als referenzzeiten 😉 hm... irgendwie habsch heut n denkprob... HILFE !!!!



  • Meinst du so etwas? 🙂

    #include <iostream>
    
    void func(char*& p) // Referenz auf Zeiger
    {
        delete[] p; // was bringt das hier?
        p = new char[100]; // und das?
        strcpy(p, "test"); // warum nicht gleich bloß hereinkopieren?
    }
    
    int main()
    {
        char* p = new char[100];
        func(p);
        std::cout << p << std::endl;
        delete[] p;
    }
    


  • ChrissiB schrieb:

    Meinst du so etwas? 🙂
    [cpp]
    #include <iostream>
    #include <fstream>

    void func(char*& p) // Referenz auf Zeiger
    {
    delete[] p; // was bringt das hier? << bei übergabe ohne speicherzuweisung
    //spukt der sonst nen Laufzeitfehler
    //(VC++)

    ifstream in("test.dat",ios::binary);
    if(in)
    {
    in.seekg(0,ios::end);

    int size = in.tellg();

    in.seekg(0,ios::beg);

    in.read((char*)p,size);

    p = new char[size]; // <<< darum in der funktion das new...
    //quasi will ich den inhalt einer datei haben und
    //damit außerhalb der funktion weiterarbeiten...
    in.close();
    }
    }

    int main()
    {
    char* p = new char[100]; // << nee,.. es geht darum dass ich vorher nich
    //weiß wieviel speicher ich brauche das bekomme
    // ich erst in der funktion raus, siehe
    //kommentar bei funktion
    func(p);
    std::cout << p << std::endl;
    delete[] p;
    }
    [/c pp]



  • Gehe dein Problem anders an. In der FAQ ist nen schöner Beitrag: http://www.c-plusplus.net/forum/viewtopic-var-t-is-39469.html

    HumeSikkins schrieb:

    Das erste Beispiel liest eine Datei zeilenweise ein und speichert
    jede Zeile in einem string-Vector. Als letztes wird der Inhalt des
    Vektors (und damit der Inhalt der Datei) nach cout geschrieben.
    Benötigte Header: <iostream>, <fstream>, <vector>, <string> und <iterator>

    using namespace std;
    ifstream FileIn("Main.cpp");
    if (FileIn)     // Falls FileIn gültig ist.
    {
        vector<string> Contents;              // Container für die einzelnen Zeilen
    
        // Solange kein Fehler auftritt und nicht eof
        for (string ReadString; getline(FileIn, ReadString); )        
            Contents.push_back(ReadString);   // Aktuelle Zeile in den Vektor einfügen
           
        /* Original:
        // Alle Elemente des Vektors ausgeben.
        ostream_iterator<string> Out(cout, "\n");
        copy(Contents.begin(), Contents.end(), Out);
        */
        // arbeite hier mit den Daten weiter  :sunglasses: 
        // Contents[0] hast du z.B. die erste Zeile als std::string
    }
    


  • hm.. ja es soll aber ne binärdatei sein 😉 und die sind ja nich zeilenweise, also da steht der mist ja in einer zeile... quasi will ich damit jede datei einlesen können... und da muss es ja binär geöffnet werden..

    EDIT: ja wie im zweiten beispiel hat.. nur will ich den inhalt aus der funktion raus transferienen 😉 also noch weiterverwenden und nicht den buffer gleich weider löschen...... wie man mit dateien umgeht weiß ich ja...



  • Welches Problem hast du nun? Ich habe dir doch schon gesagt, wie du es machen kannst. Mit diesem FAQ Beitrag und meinem Posting kannst du doch das nun einfach kompinieren. Da der new-Operator die Daten auf dem Heap anlegt, existieren die Daten auf die der Zeiger zeigt nach dem Funktionaufruf ja noch. Du kannst also ganz normal mit denen arbeiten. Am Schluss noch alles deleten und das war es schon.

    Warum definierst du den Zeiger eigentlich in der main(). Ich hätte es so irgendwie gemacht:

    char* GetFileContents(const char* file)
    {
        // siehe FAQ zum Öffnen
        char* p = new char[FileSize];
        // alles weitere
        return p;
    }
    
    // in main() dann
    char* contents = GetFileContents("file");
    


  • 1. warum in der main ? ich wollte keine globale var. haben... und er steht ja auch net in der main in meinem richtigen prog 😉 war ja nurn beispiel 😛

    2. ich kann des net mit rückgabewert machen weil ich ja noch andere werte zurückgeben will, quasi größe der datei und so weiter und sofort..bla und keks



  • mightymop schrieb:

    1. warum in der main ? ich wollte keine globale var. haben... und er steht ja auch net in der main in meinem richtigen prog 😉 war ja nurn beispiel 😛

    Naja, wie gesagt würde ich es per Rückgabewert machen. Für das ist er ja da.

    mightymop schrieb:

    2. ich kann des net mit rückgabewert machen weil ich ja noch andere werte zurückgeben will, quasi größe der datei und so weiter und sofort..bla und keks

    Hm.. du kannst boost::tuple nehmen 🕶 ( http://www.boost.org/libs/tuple/doc/tuple_users_guide.html ) und dann dies auch zurückgeben, damit du damit weiterarbeiten kannst.

    Deine Funktion könnte z.B. GetFileInfo() heißen.



  • [quote="ChrissiB"]

    mightymop schrieb:

    Hm.. du kannst boost::tuple nehmen 🕶 ( http://www.boost.org/libs/tuple/doc/tuple_users_guide.html ) und dann dies auch zurückgeben, damit du damit weiterarbeiten kannst.

    Deine Funktion könnte z.B. GetFileInfo() heißen.

    hmsl ich wollt aber meen code möglichst klein halten also ohne viele zusätliche libs... des ging ja schon mal nur weiß ich nimmer genau wie das war.. ich glaub noch zu wissen dass da irgendwie n pointer auf pointer auf bla und keks ne rolle spielte hm.. 😕 hm.......



  • Ich habe mir den Thread zwar nicht genau durchgelesen, aber man könnte doch auch einfach die verbleibenden Werte z.B. per Referenz zurückgeben.

    Also:

    //In main:
    char* buff = func(int file_size, int other_important_var);
    
    // func()
    char* func(int& fs, int& oiv)
    {
             // Verbleibenden Werte in fs und oiv schreiben.
             // und die Adresse des dynamisch reservierten Speicher 
             // per return zurückgeben.
    }
    

    Caipi



  • Caipi schrieb:

    Ich habe mir den Thread zwar nicht genau durchgelesen, aber man könnte doch auch einfach die verbleibenden Werte z.B. per Referenz zurückgeben.
    Caipi

    ja des wär auch ne möglichkeit, hm.. wollte es aber irgendwie über pointer lösen hm.. naja ok dann halt so 😛
    mich wurmts ja nur, dass ich das schon mal hatte und dann hab ichs vergessen tztz nächstes mal mach ich mir vom source ne wandtapete damit ichs net vergess



  • Es gäbe auch noch die Möglichkeit ein struct zu definieren mit den Infos.

    struct FileInfo
    {
        char* contents;
        unsigned int size;
        // lala
        FileInfo(char* contents, int size) : contents(contens), size(size)
        {}
    };
    

    Und dann eben das Objekt der Struktur returnen.

    Caipi: Joa. Man könnte auch in der main() die Größe deklarieren, diese per Referenz an die Funktion übergeben und in der Funktion die Werte ändern, wo sie danach auch in main() geändert wären. 🙄



  • @ChrissiB:
    Ich musste dir bzg. boost::tuple halt kontra bieten 😉

    Caipi



  • Caipi schrieb:

    @ChrissiB:
    Ich musste dir bzg. boost::tuple halt kontra bieten 😉

    Caipi

    😃 boost::tuple ist imho die schönste Lösung. (wenn es nicht noch irgendwas gibt, was ich nicht bedacht / gewusst habe)


Log in to reply