Shallow Copy (flächige Kopie) kopiert nur die Werte der Klassenmitglieder, einschließlich der Zeiger — kopiert jedoch nicht die Daten hinter diesen Zeigern. Deep Copy (tiefe Kopie) erstellt neue Kopien der Daten, die hinter den Zeigern liegen, wodurch eine gemeinsame Speicherverwaltung und doppelte Befreiung vermieden wird.
Beispiel:
class Buffer { public: Buffer(size_t size) : size(size), data(new int[size]) {} // Shallow copy (falsch) Buffer(const Buffer& other) : size(other.size), data(other.data) {} // Deep copy (richtig) Buffer& operator=(const Buffer& other) { if (this != &other) { delete[] data; size = other.size; data = new int[size]; std::copy(other.data, other.data + size, data); } return *this; } ~Buffer() { delete[] data; } private: size_t size; int* data; };
Wenn eine Klasse einen Zeiger auf ein dynamisches Array enthält, warum reicht es nicht aus, den Standard-Kopierkonstruktor und den Zuweisungsoperator zu verwenden?
Richtige Antwort:
Die Standardkopie implementiert eine flächige Kopie. Zwei Objekte zeigen auf dasselbe Array, und bei der Zerstörung gibt es einen doppelten Versuch, denselben Speicher freizugeben (double free), was zu einem Absturz führt.
Geschichte In einer großen Serveranwendung wurde eine eigene Klasse Image implementiert, die einen dynamischen Puffer für Pixel verwaltete. Die Entwickler implementierten keine tiefe Kopie, und beim Übergeben von Image-Objekten durch Wert zwischen Threads kam es zu doppelten Speicherfreigaben, was alle paar Tage zu Abstürzen führte.
Geschichte In einem Studentenprojekt wurde ein Container Field verwendet, der einen Zeiger auf ein dynamisch zugewiesenes Array von Zellen enthielt. Bei der Änderung der Größe des Arrays kopierte der Kopierkonstruktor nur den Zeiger, und beide Container arbeiteten mit demselben Speicherbereich, was zu inkonsistenten Daten und schwer auffindbaren Bugs führte.
Geschichte Im alten C++-Code einer Grafik-Engine wurde eine Klasse Texture ohne eigenen Destruktor und Zuweisungsoperator implementiert, was zu Speicherlecks bei der Kopie und Zuweisung von temporären Texture-Objekten führte.