Zuweisungsoperatorüberladung -> uninizialisierte Zeiger
-
Hallo an Alle,
ich bin noch recht neu in der ganzen C++ Welt, habe sonst viel mit C# und ein wenig mit C gemacht, also bitte ich darum meine (höchst wahrscheinlich) Noobige Frage zu entschuldigen
Und zwar habe ich eine Klasse A die eine private Member vom Typ char * hat. Dieser wird im Konstruktor mit NULL bzw. 0 initialisiert. Außerdem ist der Kopierkonstruktor und die operator= Methode implementiert.
Dann habe ich eine Klasse B mit einem privaten Member vom Typ A. Dem Konstruktor muss A übergeben werden, folglich wird die operator= Methode von A aufgerufen.
Das Problem ist, dass in dieser Methode auf der Source Seite die Zeiger nicht initialisiert sind und auf irgendwas zeigen. Wird in A Speicher für char * reserviert, tritt das Problem nicht auf.Hier mal der Source-Code dazu. Die Anwendung crasht beim delete. Aber eigentlich dürfte delete nie aufgerufen werden, weil die Zeiger ja NULL sein müssten.
Kompiliert hab ich es unter Linux mit g++;#include <string.h> #include <stdio.h> #include <stdlib.h> class A { private: char *key; size_t key_size; public: A() { key = NULL; key_size = 0; } A(const A& src) { if(src.key != NULL) { this->key = new char[src.key_size]; memcpy(this->key, src.key, src.key_size); this->key_size = src.key_size; } } ~A() { // this->key sollte NULL sein ist es aber nicht, warum auch immer if(this->key != NULL) delete this->key; } A &operator = (const A &src) { if(this != &src) { // src.key sollte NULL sein ist es aber nicht, warum auch immer if(src.key != NULL) { this->key = new char[src.key_size]; memcpy(this->key, src.key, src.key_size); this->key_size = src.key_size; } } } }; class B { private: A a; public: B(A a) { this->a = a; } }; int main(int argc, char** argv) { A a; B *b = new B(a); delete b; return 0; }
Schon mal vielen Dank für eure Mühen und die Aufklärung des Sachverhalts.
-
nanohcv schrieb:
A(const A& src) { if(src.key != NULL) { this->key = new char[src.key_size]; memcpy(this->key, src.key, src.key_size); this->key_size = src.key_size; } }
Überleg mal was in deinem Copy-Constructor passiert wenn
src.key NULL
ist. Wie wird dannkey
undkey_size
von dem neuen Objekt initialisiert?PS: Ein Check auf ungleich
NULL
beimdelete
ist unnötig, dadelete
bei einemNULL
Pointer gar nichts macht.
-
Ach ja, so einfach.
Manchmal sieht man den Wald vor lauter Bäumen nicht.Besten Dank.
-
Wenn wir schon dabei sind: std::string statt diesem char-zeigergefuchtel und nimm die ollen c-header raus. Alles in der c-standardbibliothek, die teil der von c++ ist, solltest du mit einem c davor includen: string.h -> cstring etc. Generell gibt es aber keinen grund, diese einzubinden, außer vielleicht dinge wie cstdint.
Soweit wie möglich auf allokationen mit new verzichten. Wenn, dann kommen smartpointer, zb unique_ptr, zum einsatz.