[C++] Problem mit Zeigern in einer Klasse

radazong

Mitglied
Hallo Leute,

Ich habe jetzt nach ca einer Woche Suchen aufgegeben. Manchmal ist der Teufel ja ein Eichhörnchen, daher wende ich mich jetzt einfach mal an euch :).

Ich habe eine Klasse, in der ich im Konstruktor Speicher auf dem Heap anfordere. Diesen wiederum gebe ich natürlich im Destruktor frei. Das funktioniert auch soweit für einzelne Objekte ganz gut. Wenn ich nun allerdings eine std::list mit Kopien dieser Objekte anlege, und das Programm beende, bekomme ich folgende Fehlermeldung:

Access violation reading location 0xcdcdcdc1.

Es ist auch immer die selbe Adresse. Kommentiere ich nun allerdings das delete[] im Destruktor aus, so läuft das Programm einwandfrei. Ich hab echt keine Ahnung wo mein Fehler liegen könnte. Daher hier mal ein bisschen Code:

C++:
//class.h

class CLASS
{
//..
int* Arr;

//....

public:

CLASS();
CLASS(const CLASS&);
~CLASS();

//...

};


//class.cpp

CLASS::CLASS()
{
  Arr=new int[/*Größe wird durch Konstruktorübergabeparameter bestimmt*/];
}

CLASS::CLASS(const CLASS& classA)
{
delete[] Arr;

Arr=new int[sizeof(classA.Arr)];

for(int i=0;i<sizeof(classA.Arr);i++)
  Arr[i]=classA.Arr[i];
}

CLASS::~CLASS()
{
delete[] Arr;
}



//main.cpp

std::list<CLASS> ClassList;
CLASS classObject;

// Zuweisungen an CLASS Objekt

ClassList.push_back(classObject);
//...

Das ist natürlich seeehr stark vereinfacht, aber ich hab soweit alles was mit dem Zeiger zu tun hat auskommentiert, sodass dies wirklich die einzigen beiden Aufrufe im Kon- und Destruktor sind. Vielleicht gibt es ja noch etwas beim zerstören von Objekten in Listen zu beachten?
Und der Fehler tritt erst beim beenden, sprich - dem Zerstören der Kopien in der std::list- auf.

Ich hoffe hier kann mir jemand Licht in Dunkel bringen,

Ein schönes Wochenende!
 
Zuletzt bearbeitet von einem Moderator:
Hi.

Du hast die Regel der großen Drei http://en.wikipedia.org/wiki/Rule_of_three_(C++_programming) verletzt und vergessen den Zuweisungsoperator zu implementieren.

Übrigens, im Kopierkonstruktor delete[] Arr; aufzurufen ist sinnfrei. Durch den Konstruktor wird gerade ein Objekt erstellt, das kann noch gar keinen Speicher haben - es existiert ja noch gar nicht.

Gruß

PS: Und sizeof(classA.Arr) ist konstant (4 auf 32 Bit Maschinen).
 
Zuletzt bearbeitet:
Hallo!
Vielen Dank erstmal für deine schnelle Antwort.
Von der Regel der großen Drei habe ich noch nicht wirklich etwas gehört. Also wird intern in der std::list auch mit dem Zuweisungsoperator des Objektes gearbeitet?

Okay, das mit dem delete im KopieKonstruktor ist wirklich relativ sinnbefreit - hab mir nicht bewusst gemacht, zu welcher Zeit dieser aufgerufen wird.

Mit dem sizeof des Zeigers hatt ich irgendwie soetwas noch im Hinterkopf - aber ist ja auch nachvollziehbar.

Nun habe ich allerdings eine weitere Frage:
Ich habe innerhalb dieser Klasse eine Funktion, die das Array neu besetzt, und gegebenenfalls auch die Größe ändern soll. Wenn ich allerdings den Speicher per delete[] freigebe, bekomme ich wieder o.g. Fehler.
Kommentiere ich diesen aus, kommt es nicht dazu. Oder brauche ich das delete an dieser Stelle nicht und kann einfach einen neuen Speicher a 'la realloc per new anfordern ohne den alten zu löschen?

Irgendwie stehe ich damit etwas auf Kriegsfuß.

Gruß
 
Du solltest unbedingt den Pointer auf NULL initialisieren. Wenn du es nicht machst, hast du unter Debug den Wert 0xcdcdcdcd drin stehen, unter Release irgend etwas Zufälliges.

Ein delete oder delete[] auf NULL macht kein Problem, aber auf einen zufälligen Wert gibt's Ärger.

Beim Vergrössern des Arrays musst du schon auch delete[] aufrufen, sonst gibt das ein Speicherleck.
 
Zurück