2015-09-10 25 views
6

new [] tarafından oluşturulan bir işaretçi üzerine delete [] yazdığımızda, program dizideki muhasebe bilgilerini arayacak ve dizinin öğe boyutunu (bir sayaç) bulacaktır. Daha sonra program, her birinin öğesinin yıkıcısını çağırır. Son olarak, bellek (ne bellek?) operator delete adlı bir işlev tarafından ayrılır.[] İmha makinelerini çağırdıktan sonra [] bir bellekte belleği ayırır mı?

Ne Soruyorum delete[] onu bu bilgilerin (toplam bellek miktarı) sonra tüm unsurları yok edilir kullanılabilir olduğundan tek atışla yılında, new[] ifadeye göre ayrılan tüm bellek ayırması ya olacak mı olacağı ardışık olarak, çalıştırdığı yıkıcıları çalıştırdığı dizi elemanları tarafından saklanan belleği ayırır?

ilgili bir izlem quesion Does delete (non array form) know the total amount of memory allocated by either new or new[]

+2

Ben senin sorunun cevabı özgürdürler 'malloc' tarafından döndürülen tahsisi boyutunu bilmek gerekir' mu –

+3

derleyici ve işletim sistemi tarafından yerine getirilmesine bağlı olduğu düşünebilirdi? –

+2

C++ standardı, "delete" ifadelerinin varsayılan davranışı hakkında bir şey söylüyor mu? – Rich

cevap

2

Tüm bellek bir kerede temel ayırıcıya bırakılacaktır. Bu, özellikle açıkça olmasa da, C++ standardı tarafından zorunlu kılınır. N3337, çevrimiçi olarak mevcut olan resmi C++ 11 standardına en yakın yaklaşımdır. delete[] çağrısının genişletileceği kodu belirten bölüm 5.3.5, [expr.delete] bölümüne bakın.Özellikle, operator delete[] sonra yıkıcı dizisi (aşama 6), tüm elemanları için çağrılan edilmiştir, adım 7'de kez olarak adlandırılır.

Ayrıca [new.delete.array] işaretçileri operator delete[] geçmek geçerlidir ilgili ne 18.6.1.2 yılında ifadeler ile bu davranışı çıkarabiliriz:" ... (operator new[] daha erken çağrı tarafından döndürülen değer olacaktır ... uyarılar ...) ". operator new[], tüm diziye bir işaretçi döndürdüğünden, bir dizi için de bir kez operator delete[] çağrılmalıdır.

1

5.3.5/2 istenir:

Birinci alternatifte

(nesneyi silme), arasında işlenen değeri bir boş olabilir silme işaretçi değeri, bir önceki yeni ifadenin oluşturduğu bir dizi olmayan nesneye işaret eden veya böyle bir nesnenin temel sınıfını temsil eden bir alt nesne olan (1.8) işaretçisidir (Madde 10). Değilse, davranışı tanımlanmamıştır.

Bu açıkça önerdiğiniz durumda davranış "bellek sızıntısı değil" ya da iki büyük olasılıkla tanımsız davranışları (oldu da yığın bozulması gibi görünüyor "bellek sızıntı" bırakır standardı tarafından tanımlanmamış olduğunu göstermektedir sadece tamlık için çok daha az olası üçüncü olasılık). Sadece böyle bir kod yazmayın ve olası sorunlardan kaçının. Uygulamada senin örneğin

auto pi = new int[10]; 
... 
delete pi; 

inşaat iyi ve çalışma programlarında oldukça yaygındır yılında

0

. Standartlara bakıp, tanımlanmamış davranışlara sahip olanlara güveneceğim. Bu yüzden rutin olarak çalıştığı gerçeğinden yararlanmanızı önermeyeceğim. Uygulamada, allocator toplam büyüklüğün kaydını tutar ve ayrılmanın doğru toplam büyüklüğünü serbest bırakır, bu nedenle yeni [] ile silme, yalnızca sıfırıncı öğelerin yıkıcılarının çağrılmasına neden olmaz ve nesnelerin dizilerine zarar vermez. önemsiz yıkım. Ancak, tanımlanmamış davranışların kodlanması, her derleyicinin belirli UB için iyi davrandığından emin olduğunuzda bile harika bir fikir değildir.

Düzenleme: şimdi asıl soruya sadece daha önemsiz bir kısmını sormak sorunuza gelen tüm bu çıkardıkları yönündeki: Öyle bir uygulama ya yapabileceğini, standart tür detaya gitmez varsayalım

. Ama aynı zamanda gerçek bir uygulamanın, tüm yıkıcıları aradıktan sonra tek bir atışta tüm bitişik parçayı serbest bıraktığından eminim. (Uygulamanın, [] seçeneğinin geçersiz kılındığı durumlar için aklı başına bir yol yapmak da gerekmezdi)

+0

-up sorusu http://stackoverflow.com/questions/32508952/does-delete-non-array-form-know-the-total-amount-of-memory-allocated-by-either adresine taşınır. – Rich

İlgili konular