10 Temmuz 2018 Salı

new operator kullanımı - new expression

Giriş
"new operator" ve "operator new" farklı şeylerdir. Ve bence çok kötü bir isimlendirme yapılmış.
  • "operator new" aynı C'deki malloc gibi raw bellek alanı döndürür. 
  • "new operator" ise C++ dilindeki bir anahtar kelimedir. Bu anahtar kelimeyi gören derleyici kod üretir.
operator new aynı zamanda "new expression" olarak ta bilinir.

New Operator
"new operator" ' ünün 3 şekli bulunur. Bunlar sırasıyla şöyledir:

1. Normal new
2. Null Döndüren new
3. Placement new
3. Kendi new metodum
"new operator" için derleyici arka planda kod üretir. "new operator için üretilen kod" yazısında detayları açıklamaya çalıştım.

New ve Free'nin Karıştırılması
new ile ayrılan bellek alanı asla free ile silinmemelidir.

New İle Ayrılan Belleğin C Metodunda Kullanılması
Bu konuda bir problem bulunmuyor. new ile ayrılan bellek alanı C metodlarında kullanılabilir. Tek koşul olarak C kütüphanesinin belleği free etmemesi gerekir diyebilirim.
int *p = new int(42);
lib_func(p);
delete p;
New Komutu Optimize Out Edilebilir
C++14 standardına göre kullanılmadığı belirlenen new komutu dikkate alınmayarak kod üretilmeyebilir.
An implementation is allowed to omit a call to a replaceable global allocation function (18.6.1.1, 18.6.1.2). When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression.
1. Normal New Kullanımı
Bu kullanım şeklinde verilen nesne heap'te yaratılır. Eğer yer kalmamışsa std::bad_alloc atılır. Bu durumda genelde de aşağıdaki mesaj ile uygulama sonlanır.
terminate called after throwing an instance of std::bad_alloc
what(): std::bad_alloc
Aborted(core dumped)
1.1 Kendi Constructor'ımızın Exception Fırlatması
Constructor İçinde Exception Fırlatmak yazısına taşıdım.

2. Null Döndüren New Kullanımı
Bu kullanım şeklinde nesne heap'te yaratılır. Eğer yer kalmamışsa çağrı null döner. Çok eskiden yani Turbo C++ zamanlarında C++'ın default çalışma modeli null döndürmek şeklindeydi. Sonradan default çalışma modeli exception atmaya döndü. Null döndüren new kullanmak için null çağrısının içine std::nothrow parametresini geçmek gerekir. Şöyle yaparız.
SomeType *p = new(std::nothrow) SomeType;
Integral tipleri kullanan bir başka örnek şöyle
int* mem = new (std::nothrow) int[100];
std::nothrow <new> dosyasında tanımlı boş bir sınıf. Açıklaması şöyle
std::nothrow is a constant of type std::nothrow_t used to disambiguate the overloads of throwing and non-throwing allocation functions.
std::nothrow ve std::noexcept farklı tipler. Bazen karıştırılabiliyorlar.

Null döndüren new kullanmanın masaüstü uygulamalarında ne avantajı var bilmiyorum. Her tarafa 
"if " koşulu koyulmasına sebep oluyor.
T *p = new (std::nothrow) T(args);

if ( p == nullptr ) //must check for nullity
{
     std::cout << "memory allocation failed" << std::endl;
}

3. Placement New Kullanımı
Placement New yazısına taşıdım.

4. Kendi new metodum
Açıklaması şöyle.
18.6.2 Storage allocation and deallocation [new.delete]
2 Replaceable: A C ++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C ++ standard library.
Bu yöntemi bir kere gömülü bir projede pool denilen bir yapıdan bellek alıp vermek için kullandım.



1 yorum:

  1. Merhaba

    Emeğinize teşekkür ederim, çok güzel ve akıcı bir anlatım olmuş

    YanıtlaSil