tiefe objektkopien und löschen
-
hi,
hab hier 2 klassen. eine Klasse Collection und ein Klasse Set, Collections kann mehrere Sets enthalten. Nun krieg ich aber ein "doppel-löschen"Fehler wenn die destruktoren aufgerufen werden und ich raffe einfach nicht wo der zu stande kommt.
hab mir für Set einen kopierkonstruktor erzeugt, der vom reinen testen der Set-Klasse her auch zu funktionieren scheint.
#ifndef COLLECTION_H #define COLLECTION_H #include "Set.h" class Collection { public: Collection(); ~Collection(); void add(Set s); void print(); private: void resize(); Set * m_member; int m_count; int CUR_MAX; }; #endif ------------ Collection::Collection():m_member(0),m_count(0), CUR_MAX(10) { m_member = new Set[CUR_MAX]; } void Collection::add(Set s) { if (m_count == CUR_MAX) resize(); m_member[m_count++] = s; } void Collection::resize() { printf("Collection resize\n"); Set *temp = new Set[CUR_MAX * 2]; for (int i=0; i < m_count; i++) temp[i] = m_member[i]; //delete m_member; CUR_MAX *= 2; m_member = temp; temp = 0; } Collection::~Collection() { if (m_member != 0) { printf("Collection Destruktor\n"); delete [] m_member; m_member = 0; } }Set
#ifndef SET_H #define SET_H #include <stdarg.h> #include <stdio.h> class Set { public: Set(); ~Set(); Set(const Set &s); Set(int i, ...); //Set operator = (const Set s); void print(); private: int * m_member; //Pointer auf Mengenarray int m_count; //Anzahl Elemente der Menge }; #endif ------------------- #include "Set.h" Set::Set():m_member(0), m_count(0) { } Set::Set(int c, ...) { m_count = c; va_list vl; va_start(vl, c); m_member = new int[c]; for(int i=0; i < c; i++) m_member[i] = va_arg(vl, int); va_end(vl); } Set::Set(const Set &s) { this->m_count = s.m_count; this->m_member = new int[s.m_count]; for(int i=0; i < m_count; i++) this->m_member[i] = s.m_member[i]; } Set::~Set() { if (m_member != 0) { printf("Set Destruktor\n"); delete [] m_member; m_member = 0; } }#include "Set.h" #include "Collection.h" int main (int argc, char * const argv[]) { Set a(8, 10,20,30,40,50,60,70,80); Collection coll; coll.add(a); return 0; }
-
Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Linux/Unix in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
void Collection::resize() { printf("Collection resize\n"); Set *temp = new Set[CUR_MAX * 2]; for (int i=0; i < m_count; i++) temp[i] = m_member[i]; //delete m_member; CUR_MAX *= 2; m_member = temp; temp = 0; }Ohne das delete hast schonmal n fettes Speicherleck drin, außerdem solltest ein Array ja auch mittels delete [] m_member entfernen ...
-
Du musst auch einen assignment-operator für "Set" implementieren.
Für Collection ebenso.
Oder du verwendest einfach std::vector und std::set (oder was auch immer an Stelle von "Set" von der STL verwendet werden kann).
-
ich hab jetzt eine sehr unbefriedigenden work-around gefunden mit viel overhead und sinnlosen objekt erzeugen, aber es funktioniert ohne gelöschte sachen erneut zu löschen.
Wenn ich mit add ein Objekt zur Kollektion hinzufügen will, dann wird der Kopierkonstruktor aufgerufen. So das ich eigentlich eine Kopie haben sollte (seltsamer weise hab ich das aber nicht), wird das stack-objekt gelöscht, löscht sich auch der inhal meinr vermeintlichen kopie mit.
Hab mir dazu eine neuen Konstruktor gemacht (Pseudo-Kopierkonstruktor), den ich in der add Methode erneut aufrufe und dann als Pointer sichere.
Hier mal die Methoden:
Set::Set(int c, Set s) { m_count = c; m_elements = new int[c]; for(int i=0; i < c; i++) m_elements[i] = s.getElement(i); } Set::Set(const Set &s) { printf("Erzeuge Referenz Objektkopie von Set\n"); this->m_count = s.m_count; this->m_elements = new int[s.m_count]; for(int i=0; i < s.m_count; i++) this->m_elements[i] = s.m_elements[i]; } void Collection::add(Set s) { if (m_sets == 0) m_sets = new Set[CUR_MAX]; if (m_count == CUR_MAX) resize(); m_sets[m_count++] = *(new Set(s.getCount(), s)); //m_sets[m_count++] = s; }Es funktioniert so, aber ich versteh zum verrecken nicht was an diesem doofen Kopierkonstruktor nicht funktioniert. Mein Pseudo-Kopierkonstruktor macht afaik das selbe.....
-
hm, ok.
Mit Assignmentoperator gehts.....aber ich versteh nicht ganz wieso?
Meine Printf-Anweisungen sagen mir, dass sowohl Kopierkonsturktor, als auch AssignmentOperator-Methode aufgerufen werden.
ist das dann nicht doppelt gemoppelt?
-
asdfsdf schrieb:
Meine Printf-Anweisungen sagen mir, dass sowohl Kopierkonsturktor, als auch AssignmentOperator-Methode aufgerufen werden.
ist das dann nicht doppelt gemoppelt?
Ohne jetzt deinen Code genau durchgelesen zu haben: du übergibst die Sets als Wert, wo eine const-Referenz reichen würde. Da wird also auch nochmal überflüssigerweise kopiert.