C ++ 'da silme vs silme [] operatörleri


136

C ++ 'da deleteve delete[]operatörler arasındaki fark nedir ?


Bu soruyu ilgili bulabilirsin stackoverflow.com/questions/1913343/…
sharptooth

7
Silme ve silme [] ile ilgili sorunlar, akıllı işaretçileri sevmemin ve vector<>elimden geldiğince bir dizi yerine kullanmamın bir nedenidir .
David Thornley


@DavidThornley Akıllı işaretçiler kullanıyorsanız, yine de yazmamayı bilmeniz gerektiği anlamındaki farkı bilmeniz gerekir std::unique_ptr<int>(new int[3]), çünkü deletetanımsız bir davranış olan dizide normal çağırır . Bunun yerine kullanmanız gerekirstd::unique_ptr<int[]>
Arthur Tacca

Yanıtlar:


151

deleteOperatör bellek kaldırır ve oluşturulan tek bir nesne için yıkıcı çağırır new.

delete []Operatör ile oluşturulan nesnelerin bir dizi için bellek ve aramalar yıkıcı serbest bırakır new [].

deleteTarafından döndürülen bir işaretçi üzerinde new []veya tarafından döndürülen bir işaretçide kullanmak tanımsız davranışa neden olur.delete []new


3
İnt veya char (yapıcı / yıkıcı yok) gibi yeni bir [] ilkel tür dizisinde delete kullanmanın mutlaka tanımsız davranışa yol açıp açmayacağını merak ediyorum. İlkel türler kullanılırken dizi boyutu hiçbir yerde saklanmıyor gibi görünüyor.
thomiel

21
Standart, bu yapıldığında ne olacağını tanımlamıyorsa, derleyiciniz sizin yapmasını istediğiniz şeyi belirleyici bir şekilde yapsa bile, tanım gereği "tanımsız davranış" dır. Başka bir derleyici tamamen farklı bir şey yapabilir.
Rob K

Bu hatayı, "char ** strArray" gibi bir dizi C dizesi olduğunda yaptım. Benim yaptığım gibi bir diziniz varsa, dizi boyunca yinelemeniz ve her bir öğeyi silmeniz / serbest bırakmanız, ardından strArray'in kendisini silmeniz / serbest bırakmanız gerekir. Sahip olduğum dizide "sil []" kullanmak işe yaramıyor çünkü (yukarıdaki yorum ve cevapta belirtildiği gibi), IT DESTRUCTORS'U ÇAĞIRIYOR, aslında her yuvayı serbest bırakmıyor.
Katianie

88

delete[]Operatör silme diziler için kullanılır. deleteOperatör dizi olmayan nesnelerin kaldırılması için kullanılır. Sırasıyla, dizinin öğeleri veya dizi olmayan nesne için yıkıcıları çağırdıktan sonra (nihayetinde) işgal ettiği dizinin veya dizi olmayan nesnenin işgal ettiği belleği silmek için çağırır operator delete[]ve operator deleteişlev görür.

Aşağıdaki, ilişkileri göstermektedir:

typedef int array_type[1];

// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;

// create and destroy an int
int *b = new int;
delete b;

// create and destroy an int[1]
int *c = new int[1];
delete[] c;

// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;

Bunun newbir dizi oluşturması için (yani, bir dizi türü yapısına uygulanır new type[]veya bu newyapıya uygulanır), Standart operator new[], dizinin öğe türü sınıfında veya genel kapsamda bir arar ve istenen bellek miktarını iletir. İstediğinden daha fazlasını isteyebilir N * sizeof(ElementType)(örneğin öğelerin sayısını saklamak için, böylece daha sonra silme sırasında kaç yıkıcı çağrısının yapılacağını bilir). Sınıf operator new[], bellek miktarına ek olarak bir diğerini kabul ederse size_t, bu ikinci parametre tahsis edilen elemanların sayısını alır - bunu istediği herhangi bir amaç için kullanabilir (hata ayıklama, vb ...).

Bu, newdizi olmayan bir nesne oluşturur için operator new, elemanın sınıfında veya genel kapsamda bir arayacaktır . İstenen bellek miktarını geçirir (tam olarak sizeof(T)her zaman).

İçin, delete[]dizilerin öğe sınıf türüne bakar ve yıkıcılarını çağırır. Kullanılan operator delete[]işlev, öğe türünün sınıfındaki bir işlevdir veya hiçbiri yoksa, o zaman genel kapsamdadır.

İçin delete, eğer geçirilen işaretçi gerçek nesnenin türünün temel bir sınıfı ise, temel sınıf sanal bir yıkıcıya sahip olmalıdır (aksi takdirde, davranış tanımsızdır). Bu bir temel sınıf değilse, o sınıfın yıkıcısı çağrılır ve operator deleteo sınıfta bir veya global operator deletekullanılır. Bir temel sınıf geçildiyse, o zaman gerçek nesne türünün yıkıcısı çağrılır ve operator deletebu sınıfta bulunan kullanılır veya hiçbiri yoksa, global operator deleteçağrılır. Eğer operator deletesınıfta tipte ikinci bir parametresi vardır size_t, bu ayırması eleman sayısını alır.


18

Bu, c ++ malloc/ free, new/ delete, new[]/ içindeki ayırma / DE-ayırma deseninin temel kullanımıdır. delete[]

Bunları uygun şekilde kullanmamız gerekiyor. Ancak, deleteve arasındaki fark için bu özel anlayışı eklemek isterim.delete[]

1) tek bir nesnedelete için ayrılan hafızayı geri almak için kullanılır

2) nesneler dizisidelete[] için ayrılan hafızayı geri almak için kullanılır

class ABC{}

ABC *ptr = new ABC[100]

Dediğimizde new ABC[100], derleyici kaç tane nesnenin ayrılması gerektiği hakkında bilgi alabilir (burada 100'dür) ve oluşturulan nesnelerin her biri için kurucuyu çağırır.

ancak buna karşılık olarak, basitçe delete ptrbu durum için kullanırsak , derleyici kaç tane nesnenin ptrişaret ettiğini bilemeyecektir ve sadece 1 nesne için yıkıcı çağırma ve belleği silme (yıkıcıların çağrılmasını ve kalan 99 nesnenin serbest bırakılmasını bırakarak). Dolayısıyla bir bellek sızıntısı olacaktır.

bu yüzden delete [] ptrbu durumda kullanmamız gerekiyor .


3
Bu doğru cevap olmalı. Diğer yanıtların hiçbiri belirgin bir farktan bahsetmiyor: "ancak buna karşılık olarak, bu durum için sadece delete ptr kullanırsak, derleyici ptr'nin kaç nesneye işaret ettiğini bilemeyecek ve yalnızca 1 nesne için yıkıcı çağırıp belleği silecektir"
Don Larynx

1
Aynı şeyi C'de nasıl elde ederiz?
Doğuş Ural

@ DogusUral Neden? C'de yıkıcı yok, yani sadece free()şu ve bu. Sözde yıkıcı bir model kullanıyorsanız, bir fordöngü kullanan her nesne için bir kez çağırmanız gerekir .
Kotauskas

@DonLarynx'in doğru farkı, onları karıştırmanın kötü biçimlendirilmiş bir programla sonuçlanmasıdır. Bir uygulama , kaç nesnenin yok edileceğini biliyor olabilir veya olmayabilir . Yanlış çağrıldığını bilmesine ve sorunun nerede olduğunu söyleyen programı iptal etmesine izin verilir.
Caleth

6

Operatörler deleteve delete []oluşturulan nesneleri yok etmek sırasıyla kullanılır newve new[]ayrılmış bellekte dönen derleyici'nın bellek yöneticisine mevcut bıraktı.

İle oluşturulan nesnelerin newmutlaka ile yok edilmesi deleteve bununla oluşturulan dizilerin new[]silinmesi gerekir delete[].


2

Bu soruyu sorduğumda asıl sorum şuydu: "ikisi arasında bir fark var mı? Çalışma zamanının dizi boyutu hakkında bilgi tutması gerekmiyor mu ve bu nedenle hangisini kastettiğimizi söyleyemeyecek mi?" Bu soru "ilgili sorularda" görünmüyor, bu yüzden sadece benim gibilere yardımcı olmak için, işte bunun cevabı: "Silme [] operatörüne neden ihtiyacımız var?"


Geri geldiğiniz ve bunu koyduğunuz için teşekkürler.
Ziffusion

0

deletetek bir işaretçi delete[]için kullanılır ve bir diziyi bir işaretçi aracılığıyla silmek için kullanılır. Bu , daha iyi anlamanıza yardımcı olabilir.


-6

Şey .. belki de sadece açık için olduğunu düşünüyorum. Operatör deleteve operatör delete[]ayırt edilir, ancak deleteoperatör de diziyi serbest bırakabilir.

test* a = new test[100];
delete a;

Ve zaten kontrol edildiğinde bu kodda hiçbir bellek sızıntısı yok.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.