ProgramlamaC++ geliştirici, sistem programcısı

C++'da operator new/operator delete mekanizmasını anlatın. Bunlar new/delete'den nasıl farklıdır, kullanıcı sınıflarında operatör fonksiyonları ne zaman ve neden aşırı yüklenir?

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

Cevap.

C++'da operator new ve operator delete bellek ayırma ve serbest bırakma işlevleridir, bu işlevler new ve delete operatörleri ile nesne oluşturma ve silme sırasında çağrılır. Varsayılan olarak standart ayırıcıyı kullanır, ancak sınıfta bellek ayrımını ince bir şekilde kontrol etmek için aşırı yüklenebilir.

  • operator new "ham" bir bellek bloğu ayırır, bu işlemde yapıcı çağrılmaz.
  • Bellek ayrıldıktan sonra nesnenin yapıcısı otomatik olarak çağrılır.
  • operator delete bellek serbest bırakma işlemini, nesnenin yıkıcısı tamamlandıktan sonra gerçekleştirir.

Kullanım (küresel ve yerel versiyonlar):

  • Küresel versiyon varsayılan olarak kullanılır (örneğin, new int).\n- Sınıfta belirli bir operator new'yi aşırı yükleyerek, bu sınıf için nesnelerin bellek yönetimini optimize edebilirsiniz (örneğin, nesne havuzu, izleme, blokların yeniden kullanımı).\n

operator new/operator delete'in aşırı yüklenmesi örneği:

#include <iostream> class TrackAlloc { public: void* operator new(size_t size) { std::cout << "TrackAlloc::new için " << size << " bayt "; return ::operator new(size); } void operator delete(void* ptr) { std::cout << "TrackAlloc::delete "; ::operator delete(ptr); } };

İncelikler:

  • Arguanlarla nesnelerin yeni/serbest bırakılması (placement new) ayrı bir aşırı yükleme gerektirir.
  • Aşırı yüklenmiş operatörler yalnızca sınıf nesneleri oluşturulurken/silinirken çağrılır, new[]/delete[] için değil. Onlar için ayrı operator new[]/delete[] aşırı yüklenebilir.
  • Bellek yönetimi tehlikelidir — sinyallerin doğru bir şekilde işlenmesi gerekir.

Kandırmaca Sorusu.

"Bir sınıfta operator new'yi aşırı yüklediyseniz, ardından bir türetilmiş sınıf değişkeni aracılığıyla bir nesne oluşturduğunuzda ne olur? Hangi operator new versiyonu çağrılacak?"

Cevap: Nesne oluşturulurken çağrılan sınıfın operator new'yi çağıracaktır. Eğer türetilmiş sınıfın operator new'si yoksa, uygun versiyonu bulmak için temel sınıfa veya küresel versiyona bakılacaktır.

Örnek:

struct Base { void* operator new(size_t s) { std::cout << "Base new "; return ::operator new(s); } }; struct Derived : Base {}; Derived* p = new Derived; // Base::operator new!'yi çağırır!

Konunun inceliklerini bilmemekle ilgili gerçek hata örnekleri.


Hikaye

Geliştiriciler operator new/ delete'yi doğru sinyal işleme desteği olmadan aşırı yüklediler. Yapıcı içinde bir istisna atıldığında bellek serbest bırakılmadı, bu da bellek sızıntısına yol açtı.


Hikaye

operator new[] ve operator delete[] yanlış uygulandı: dizileri barındıran bir sınıf için yeni uygulama çağrılmadı — varsayılan versiyonlar kullanıldı, bu da bellek ayırma ve serbest bırakma mantığının senkronizasyonunu bozdu.


Hikaye

Küresel operator new'yi aşırı yüklemek üçüncü taraf kütüphanelerin çalışmasını etkiledi: tüm nesneler (geçici ve STL'den) kaydedilen ayırıcı ile ayrılmaya başlandı, bu da uygulamanın çekirdek performansını kritik şekilde yavaşlattı.