Automatische Speicherreservierung von Strukturen



  • Hi,

    ich möchte eine Funktion schreiben, in der ich automatisch Speicher für verschiedene Strukturen reservieren möchte.
    Jetzt habe ich nur das Prob, wie übergebe ich verschiedene Strukturen in diese Funktion.

    Hier die Funktion:

    struck_gfx2d				*gfx2d; //global
    struck_planeten				*planeten;
    void speicherverwaltung_funktion::add(int anzahl)
    {
    struck_gfx2d *tmp_obj = new struck_gfx2d[gfx2d[0].anzahl+anzahl];
    for(unsigned int i2 = 0; i2 < gfx2d[0].anzahl; ++i2)
    {
    	tmp_obj[i2] = gfx2d[i2]; 
    }
    delete [] gfx2d;
    gfx2d = NULL;
    gfx2d = new struck_gfx2d[i2+anzahl];
    for(i2 = 0; i2 < tmp_obj[0].anzahl+anzahl; ++i2)
    {
    	gfx2d[i2] = tmp_obj[i2];
    }
    delete [] tmp_obj;
    tmp_obj = NULL;
    gfx2d[0].anzahl = i2;
    }
    

    Jetzt möchte ich das aber so haben, das ich die Funktion so aufrufen kann das die Struktur gleich mitgebe.
    So wie sie oben steht, kann ich ja nur "struck_gfx2d" bearbeiten.
    Ich möchte aber eine Funktion wo ich "struck_gfx2d" und "struck_planeten" Speicher reservieren kann.
    Sprich, ich muss der Funktion die Struktur übergeben, ich habe aber keine Ahnung wie.



  • Entweder als Pointer auf einen Pointer, oder antürlich viel besser: Eine Klasse bei der du im Konstruktor (oder in einer anderen Methode) den Speicherreservierst und dann wieder im Destruktor frei gibst.

    Gruß



  • Für ein kleines Beispiel wäre ich sehr dankbar 🙂



  • Ich machs mal mit int, macht ja kein Unterschied.

    void holMirSpeicher(int** address, size_t size)
    {
        *address = new int[size];
    }
    

    Der Nachteil an dieser Methode ist ganz klar dass du den Speicher wieder freigeben muss, das vergisst man sehr sehr sehr schnell. Vor allem wenn man im Team programmiert und keiner den Code vom anderen kennt.

    Da ist doch so viel besser:

    class meinKleinerIntSpeicher
    {
    public:
        meinKleinerIntSpeicher(size_t size) : pointer(new int[size]) { }
        ~meinKleinerIntSpeicher() { delete[] pointer; }
        int get(size_t pos) { return pointer[pos]; }
        void set(size_t pos, int val) { pointer[pos] = val; }
    private:
        int* pointer;
    };
    

    Der Speicher wird hier automatisch freigebene wenn das Objekt zerstört wird.

    Gruß



  • struck_gfx2d
    *speicherverwaltung_funktion::add (struck_gfx2d *gfx2d, int anzahl) 
    { 
      struck_gfx2d *tmp_obj = new struck_gfx2d[gfx2d[0].anzahl+anzahl]; 
    
      for(unsigned int i=0; i<gfx2d[0].anzahl; ++i) 
        tmp_obj[i]=gfx2d[i]; 
    
      delete[] gfx2d; 
    
      gfx2d           = tmp_obj;
      gfx2d[0].anzahl = i;
    
      return gfx2d;
    }
    

    an deiner stelle würde ich aber die vector-klasse der stl benutzen. die kann alles, was auch c-arrays können, vergrößert aber ihren speicher bei bedarf automatisch.



  • @FireFlow

    Kann sein das ich auf den Kopf gefallen bin, aber zeig mir mal bitte, wie du in deinem Beispiel einen float übergibst. So wie ich es verstehe geht das ja bei dir nur mit int.

    Deiner Funktion übergeb ich ja die Adresse eines int, was passiert aber wenn Speicher für einen float reservieren möchte ?

    @Konfusius
    Ich möchte aber ein und die selbe Funktion für verschiedene Strukturen nutzen können, nicht nur für struck_gfx2d.

    Aber du kannst mir zeigen, wie ich folgende Struktur

    typedef struct base_TYP
    {	
    int	anzahl;
    char	ressource[100];
    } base;
    

    in einen vector bekomme und dann auf die einzelnen inhalte (anzhal, ressource) zugreifen kann.

    Den vector anlegen ist klar
    typedef vector<base> ressourcen;

    aber wie bekomme ich dann daten wieder aus dem vector heraus ?



  • template<class TYPE>
    TYPE
    *speicherverwaltung_funktion::add (TYPE *array, int anzahl) 
    { 
      TYPE *tmp_obj = new TYPE[array[0].anzahl+anzahl]; 
    
      for(unsigned int i=0; i<array[0].anzahl; ++i) 
        tmp_obj[i]=array[i];
    
      tmp_obj[0].anzahl=i;
    
      delete[] array; 
    
      return tmp_obj;
    }
    

    das klappt aber nur, wenn alle typen es erlauben, die länge des arrays über array[0].anzahl zu bestimmen. außerdem muß diese funktion dann im header stehen. separate kompilation ist mit templates nämlich nur sehr eingeschränkt möglich.



  • BlackWolf schrieb:

    @FireFlow

    Kann sein das ich auf den Kopf gefallen bin, aber zeig mir mal bitte, wie du in deinem Beispiel einen float übergibst. So wie ich es verstehe geht das ja bei dir nur mit int.

    Das war wie gesagt nur beispielhaft. Du kannst wie schon gesagt Templates benutzen, oder eigentlich noch besser (wie auch schon gesagt -lol) ein Container aus der STL.

    Gruß



  • Die Funktion geht, aber beim aufruf habe ich probs.

    speicherverwaltung_funktion	*v_speicherverwaltung;
    struck_ressourcen_base		*ressourcen;
    v_speicherverwaltung->add(ressourcen,1);
    

    Dann kommt folgende Fehlermeldung:
    start.obj : error LNK2001: Nichtaufgeloestes externes Symbol "public: ...."



  • Dann wär's das beste sich zu überlegen, wie man den Fehler beseitigt.

    Bye, TGGC (Demo or Die)



  • die funktion ist ein sogenanntes member-template. das muß man in der klassendeklaration speziell deklarieren:

    template<class TYPE>
    TYPE *add (TYPE *array, int anzahl);
    

    außerdem mußt du die implementation der funktion mit in die headerdatei setzten.


Anmelden zum Antworten