Wie kann ich am besten ein Array von einer struktur zurückgeben ??



  • hi, ich habe ein array von einer selbstdefinierten struktur.
    nun suche ich eine möglichkeit, dieses array von einer methode zurückgeben zu lassen.

    da ich ein very new newcomer bin, bitte ich euch um hilfe !



  • du gibts einfach das array zurück, was dann letzendlich nicht mehr als ein zeiger ist. da man die größe des arrays nicht ermitteln kann, musst du die auch noch mitliefern. den zurückgegebenen zeiger kannst du wieder wie ein array benutzen.
    oder du nimmst gleich einen vector aus der STL, aber das ist für einen anfänger vielleicht doch etwas overkill.



  • Das Array einfach zurückgeben ist nicht pauschal immer erlaubt, da es auf dem Stack liegen kann. std::vector klingt schon viel besser.



  • Optimizer schrieb:

    Das Array einfach zurückgeben ist nicht pauschal immer erlaubt, da es auf dem Stack liegen kann.

    ja, das hast du natürlich recht.

    @newcomer: das array darfst du nicht in der funktion lokal erstellt haben (also KlasseA Objekte[X]; ), das würde dann nämlich nach beenden der funktion futsch sein und dein zurückgegebener zeiger ginge ins nirvana. entweder, das array wurde schon vorher irgendwo anders erstellt, oder du erstellst es auf dem heap (mit new).



  • #include <vector>
    using namespace std;
    
    vector<Meine_Struct> mysub() {
       Meine_Struct a;
       Meine_Struct b;
       Meine_Struct c;
       vector<Meine_Struct> array;
       array.push_back(a);
       array.push_back(b);
       array.push_back(c);
    
       return array;
    }
    

    sollte gehen, wenn nicht, einfach vector<Meine_Struct> in einer Klasse kapseln

    class MyClassThatIsAVectorOfMeineStruct : public vector<Meine_Struct> {
    };
    


  • Eben, und wenn du es mit new erstellst,

    byte *getArray()
    {
        byte *array=new char[20];
        return array;
    }
    
    void init(byte *array)
    {
        array[0]=...;
        .
        .
        .
        array[20]=...;
    }
    
    int main()
    {
        byte *myArray=getArray();
        init(myArray);
        .
        .
        .
        delete[] myArray;
    }
    

    brauchste (hier in der init Funktion) nichts zurück geben da du ja einen Speicher beschreibst.



  • @gast: da wird doch das ganze array kopiert. könnte ziemlich ineffektiv werden.



  • Könnte es, angenommen, er würde das in einer sehr engen Schleife benutzen. Dafür ist deine Lösung sehr unangenehm zu handhaben. (Woher bekommt man die Größe? Womit muss man das Array freigeben? Das muss man sich aus Kommentaren erschließen.) Im Zweifelsfall sollte man lieber erstmal die Lösung benutzen, die lesbar ist.

    sollte gehen, wenn nicht, einfach vector<Meine_Struct> in einer Klasse kapseln

    Was du da gezeigt hast, hat aber nichts mit Kapselung, sondern nur mit schlechtem Design zu tun.



  • prinzipiell:

    fuer c++ der weg uber containerklassen ! wie oben beschrieben

    fuer c ... und fuer c-schnittstellen (Dlls und so, was man manchmal eben auch noch unter c++ braucht) geht man anders vor ... :

    der rueckgabewert sollte nie eine komplexe struktur sein .... (selbst strings ist schon problematisch), erst recht kein zeiger auf allokierten speicher .

    Getreu nach dem motto, der speicher sollte in dem block allokiert werden, wo er auch wieder freigegeben wird ... baut man solche schnittstellen folgendermassen :

    rueckabewert ist nen fehlcode, parameter 1 ist nen zeiger auf den Typ, parameter 2 ist nen zeiger auf die anzahl ...

    wobei die funktion 2 modies hat ....

    ist der parameter 1 gleich NULL , ermittelt die funktion nur die Anzahl der elemente die es beschreiben will, also die groesse des benoetigten arraus und chreibt es an die stelle wo parameter 2 hinzeigt.

    ist der parameter 1 ungleich null, geht die funktion von aus, dass es sich um beschreibbaren speicher handelt, und an der position wo parameter 2 hinzeigt die groesse, allso die anzahl der max schreibbaren elemente steht ....
    wurde erfolgreich das aray befuellt, wird in paramter 1 dann noch die wirkliche anzahl geschriebener elemente hinterlegt ...

    das allokieren ist damit vollig ausserhalb der funktion ...

    so machens fast alle C-Api's ... und daran sollte man sich auch halten ...

    als beispiel mit deinen GetArray sollte das so aussehen ....

    // Prototyp deiner funktion ... 
    int GetArray(byte * pData,size_t * Anzahl);
    
    // Die verwendung speichersparend .... 
    size_t anz = 0;
    
    int iret = GetArray(NULL,&anz);
    if(anz > 0 /* ... und reuckgabewert der funktion noch auswerten */ )
    {
        byte * data = new byte[anz];
        iret = GetArray(data,anz);
        // irgendwas mit dem zeugs anstellen 
        // dann speicher wieder freigeben 
        delete data;
    }
    
    // die perofrmante aber speicherintensieve verwendung sollte auch gehen, wenn man weis das nie mehr wie xxx elemente zrueckgegeben werden .... 
    
    byte data[1024];
    size_t anz = 1024;
    int iret = GetArray(data,&anz);
    
    // in anz steht nu wieviel der elemente nun geschriben wurde, sprich bis wohin das array sinvolle werte hat ....
    

    Ciao ...



  • Optimizer schrieb:

    Das Array einfach zurückgeben ist nicht pauschal immer erlaubt, da es auf dem Stack liegen kann. std::vector klingt schon viel besser.

    Hä. Und der std::vector kann nicht auf dem Stack liegen?


Log in to reply