ProgramlamaC++ geliştirici

Kopya yapıcı ve atama operatörü nedir? Dinamik bellek ile nesne kopyalamada hatalardan nasıl kaçınılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Kopya yapıcı ve kopya atama operatörü, kaynaklara (örneğin, dinamik belleğe) sahip nesnelerle çalışmak için gereklidir. Varsayılan olarak, derleyici alan alan kopyası oluşturur ki bu ham gösterici için güvenli değildir:

class Buffer { public: Buffer(size_t size) { data = new int[size]; this->size = size; } ~Buffer() { delete[] data; } // Kopya yapıcının doğru uygulanması Buffer(const Buffer& other) : size(other.size) { data = new int[size]; std::copy(other.data, other.data + size, data); } // Doğru atama operatörü 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; } private: int* data; size_t size; };

Aksi takdirde, iki nesne kopyalandığında biri belleği serbest bırakır, diğeri sarkan bir gösterici ile kalır (çift serbest bırakma veya serbest bırakmadan sonra kullanım).

Kandırmaca Soru

Sadece kopya yapıcı açıkça tanımlanırsa, atama operatörü ne olur? Ne zaman gerekir, ne zaman gerekmez?

Cevap: Eğer sadece kopya yapıcı tanımlanmış ancak atama operatörü tanımlanmamışsa, derleyici varsayılan atama operatörünü (bit bazında kopyalama) oluşturur, bu da dinamik kaynaklara sahip bir nesne için tehlikeli olacaktır; yani aynı göstericiyi iki kez serbest bırakacaktır.

Bellek yönetimi durumunda her ikisini de uygulamak gerekir: hem kopya yapıcıyı hem de atama operatörünü, kopyalama/hafıza sızıntısı hatalarından kaçınmak için.

Gerçek Hatalardan Örnekler


Hikaye

Bir medya sunucusunda, bir buffer nesnesinin kopyalanmasında kopya yapıcı kullanıldı, ancak atama operatörü unutuldu. Bir buffer diğerine atanırken, nesnelerin yok edilmesinde çift bellek serbest bırakma meydana geldi. Hata stres testlerinde ortaya çıktı.


Hikaye

Taşıma lojistiği projesinde varsayılan atama operatörü, koordinat dizisine işaret eden bir yapıyı kopyaladı. Bir nesne silindikten sonra diğeri serbest bırakılmış belleğe erişerek segmentasyon hataları oluşturuyordu.


Hikaye

Grafik kaynaklarla ilgili bir projede, nesnelerin akışlar arasında iletilmesinde kopya yapıcının uygulanması unutuldu. Değer ile iletildiğinde, yüzeysel kopyalama meydana geldi ve diğer akıştaki nesne değiştirildiğinde veri bozulması ve programın çökmesi gerçekleşti.