ProgramlamaC++ Geliştirici

Bir sınıf nesnesini bir işleve değer olarak geçirirken ne olur ve kopyalayıcı yapıcıyı uygularken dikkate alınması gereken tuzaklar nelerdir?

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

Cevap

C++'da bir nesnenin değer olarak bir işleve geçirilmesi sırasında kopyalama yapıcı kullanılarak nesnenin bir kopyası oluşturulur. Eğer sınıfta bir kullanıcı tanımlı kopyalama yapıcı belirtilmişse, işlevin geçici nesne-argümanını başlatmak için bu çağrılır. Belirtilmemişse — varsayılan derleyici kullanılır ve bu, bit düzeyinde kopyalama (shallow copy) gerçekleştirir.

Tuzaklar:

  • Eğer sınıf kaynakları yönetiyorsa (örneğin, ham işaretçilere sahipse), varsayılan olarak oluşturulan kopyalama yapıcı bellek çift serbest bırakılmasına ve bellek sızıntılarına yol açacaktır.
  • Kopyalama yapıcının kaynakları doğru bir şekilde kopyaladığından emin olmalısınız (genellikle deep copy).

Örnek:

class StringWrapper { char* data; public: StringWrapper(const char* str) { data = new char[strlen(str) + 1]; strcpy(data, str); } // Hata: shallow copy StringWrapper(const StringWrapper& other) : data(other.data) {} ~StringWrapper() { delete [] data; } }; void foo(StringWrapper s) { // ... } int main() { StringWrapper s1("hello"); foo(s1); // UB!!! return 0; }

Şaşırtıcı soru

"Eğer bir işaretçi içeren sınıfta kopyalama yapıcıyı şöyle tanımlarsak: MyClass(const MyClass &other) : data(other.data) {}? Bunun sonuçları neler olur?"

Doğru cevap: Bu kopyalama yapıcı, kopyalanan nesne ile aynı bellek alanına işaret eden bir nesne oluşturur. İki nesne yok edilirken bellek iki kez serbest bırakılacak (double free) ve bu da belirsiz bir davranışa yol açacaktır. Deep copy uygulamak gereklidir:

MyClass(const MyClass &other) { data = new int(*other.data); }

Konuyla ilgili bilgi eksikliğinden kaynaklanan gerçek hata olayları


Hikaye

Büyük bir sunucu projesinde, içinde "ham" bir dizi bulunan nesnelerin konteynerleri kullanıldı ve standart kopyalama yapıcı (shallow copy) kullanıldı. Nesneler değer olarak geçirildiğinde double free meydana geldi ve uygulamanın çökmesine neden oldu, bu durum yalnızca üretimde yakalandı.


Hikaye

Eski bir C++ kütüphanesinde, grafik tamponunu kopyalamayan bir kopyalama yapısı, bir kopya üzerine değişiklik yapılırken diğerinin değişmesine neden oldu ve beklenmedik arayüz hatalarına yol açtı.


Hikaye

Bir işlevden değerle nesne dönerken, bir iç parola saklama sisteminde geçici nesne yok edildiğinde veriler temizlendi (shallow copy) ve sonuç olarak gerçek nesne sıfırlanmış bir işaretçi tuttu, sızıntı bir güvenlik denetimi sırasında tesadüfen ortaya çıktı.