Speicherproblem bei vector in Klasse



  • Moin,
    ich habe eine Klasse, in der ich 2 vectoren vom Typ AnsiString habe. In diesen speichere ich zur Laufzeit Strings. Bei jedem Öffnen des Forms werden die Daten neu geladen, deshalb hab ich eine Klassenmethode, die mittels pop_back() die vectoren leeren soll. Das Problem ist: Er gibt den Speicher nicht frei. Wenn ich das öfters mache, steigt der Speicherverbrauch meines Programms ständig an.
    Testweise habe ich mal eine Schleife eingebaut, die den Vorgang ein paar hundert Mal macht und schon bei etwa 350 Durchläufen mit 2 Einträgen pro Vector bekomme ich einen EOutOfMemory

    Wie krieg ich den Speicher wieder ordentlich frei?

    Nochn bisschen Code:

    class Tparameter
    {
    protected:
     vector<AnsiString> params;
     vector<AnsiString> description;
     int anzahl;
     int debug;
    
    public:
    //Konstruktor
     Tparameter(int _debug)
     {
      anzahl=0;
      debug=_debug;
     }
    //Add-Methode
     void addstring(char* s,char* descript)
     {
      params.push_back(s);
      description.push_back(descript);
      anzahl++;
     }
    //Ausgabemethoden
     AnsiString readstring(int index)
     {
      return params[index];
     }
    
     AnsiString readdescription(int index)
     {
      return description[index];
     }
    
     int count()
     {
      return anzahl;
     }
    //Soll den Speicher wieder freigeben
     clear()
     {
      for (int i=0;i<anzahl;i++)
      {
       params.pop_back();
       description.pop_back();
      }
      anzahl=0;
     }
    };
    


  • kannst du mal die pop_back und push_back funktion posten?

    oder sind die VCL speziefisch? <-- ok wusste ich net *g*



  • @DreadlockFilbert:
    pop_back und push_back sind methoden der klasse vector.

    @Uwe82:
    warum benutzt du nicht einfach eine StringList?



  • Jester2000 schrieb:

    @Uwe82:
    warum benutzt du nicht einfach eine StringList?

    Jo.

    Ausserdem hat std::vector auch selbst eine clear-Methode.
    Dann scheint mir auch folgendes Codestück mehrfach unglücklich geraten:

    clear() 
     { 
      for (int i=0;i<anzahl;i++) 
      { 
       params.pop_back(); 
       description.pop_back(); 
      } 
      anzahl=0; 
     }
    

    oder eigentlich der ganze Umgang mit std::vector. Hast du dir überhaupt schonmal alle methoden von std::vector angesehen?

    std:vector hat selber eine size() oder count() (weiss nichtmehr genau welche) methode. Wieso führst du eine Schattenbuchhaltung?
    Wieso löschst du nicht einfach mit std::vector::clear?
    Wie verläuft std::vector::capacity?

    -junix

    <edit>Ausserdem: Wieso greifst du klassenintern - obwohl du eine Zugriffsmethode im Interface hast - direkt auf "anzahl" zu, anstatt über die Zugriffsmethode? Goldene Regel beim Klassendesign: Klasseninterne Daten sollten unbedingt immer auch über die zugriffsmethoden zugegriffen werden um asynchronitäten zu verhindern.</edit>



  • wäre das nicht besser:

    struct TValue
    {
    
    String Param;
    String Description;
    TValue(String P,String D):Param(P),Description(D){};
    };
    
    typedef vector <TValue*> TValueList;
    typedef vector <TValue*>::iterator TValueList_Iter;
    typedef vector <TValue*>::const_iterator TValueList_Const_Iter;
    


  • Danke schonmal für die Tipps.
    Also der Grund für anzahl ist einfach, dass die Klasse aus einer Info-Praktikum-Aufgabe kommt, da haben wir mit char*-Arrays gearbeitet. Da hab ich das dann gebraucht. Ich habe das nur wegen der einfacher zu behandelnden AnsiStrings ersetzt.

    Die clear-Methode habe ich wohl irgendwie übersehen, aber leider bringt mir das auch nichts, speichertechnisch ändert sich gar nichts.

    An die StringList habe ich irgendwie auch nicht gedacht 🙄 , aber es dürfte doch eigentlich nicht wirklich was anderes sein, als wenn ich einen Vektor mit AnsiStrings verwende?

    @AndreasW: Das wäre noch zu probieren, werde ich heute abend mal machen.

    Leider hat mich jetzt noch gar nichts weitergebracht, habe aber Eure Vorschläge mal mit reingenommen. SPeichertechnisch immer noch dasselbe Problem.

    Vorher hatte ich es auch anders: Da habe ich das Objekt in FormShow mit new erzeugt und davor mit delete gelöscht, bis ich auf die Idee gekommen bin, die Vektoren zu leeren. Jetzt erzeuge ich nur noch in FormCreate einmal die Instanz.

    Gäbe es denn eine Möglichkeit innerhalb des Objekts den Vektor im Konstruktor erst zu erzeugen und ihn im Destruktor wieder freizugeben? Ich denke, vor allem beim Destruktor hängt das Problem.... 😞


Anmelden zum Antworten